博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LockSupport类浅析
阅读量:6248 次
发布时间:2019-06-22

本文共 2620 字,大约阅读时间需要 8 分钟。

hot3.png

#1、代码应用

public class FIFOMutex {    //原子锁,类型为boolean    private final AtomicBoolean locked = new AtomicBoolean(false);    //等待队列    private final Queue
waiters = new ConcurrentLinkedQueue
(); public void lock() { //获取当前线程,添加到等待队列中 boolean wasInterrupted = false; Thread current = Thread.currentThread(); waiters.add(current); // Block while not first in queue or cannot acquire lock //如果当前线程不是在等待队列头部或者无法获取锁信息 while (waiters.peek() != current || !locked.compareAndSet(false, true)) { // 阻塞当前线程 LockSupport.park(this); //这个时候线程别打断 if (Thread.interrupted()) // ignore interrupts while waiting //忽略等待过程中线程被打断的操作 wasInterrupted = true; } //当先线程已经被走到了线程 头部,并且或者锁,将其从等待队列中删除 waiters.remove(); if (wasInterrupted) // reassert interrupt status on exit //恢复打断状态并退出 current.interrupt(); } public void unlock() { locked.set(false); //为等待队列的第一个线程解除锁定。 //peek()获取头,但是不把头从队列里面删除 LockSupport.unpark(waiters.peek()); }}

#2、源码分析

##2.1、unsafe.objectFieldOffset

LockSupport代码有一段静态的代码段。

static {    try {        parkBlockerOffset = unsafe.objectFieldOffset            (java.lang.Thread.class.getDeclaredField("parkBlocker"));    } catch (Exception ex) { throw new Error(ex); }}

该代码段中unsafe.objectFieldOffset表示的含义是定位字段相对对象初始位置的偏移量。parkBlocker是Thead类的一个字段,该字段在LockSupport中的getBlocker()和setBlocker()方法中使用。具体的含义下文将有介绍。

##2.2、unsafe.putObject

LockSupport代码在设置对象某属性值的时候使用了内部的类方法。例如设置属性字段parkBlocker的值的时候,代码片段如下。

private static void setBlocker(Thread t, Object arg) { //设置线程对象t的字段parkBlocker,值为arg unsafe.putObject(t, parkBlockerOffset, arg); } ##2.3、Thread的parkBlocker

前面两小节都在说字段parkBlocker,可见其在LockSupport实现中的重要地位。那么它的具体作用是什么?

从javadoc上来看parkBlocker字段是工具,它能够记录线程阻塞信息以便监控和分析线程阻塞原因的。 ##2.4、方法介绍 如果线程不可访问则unpark方法使得指定线程可用访问,如果线程被阻塞,unpark方法将唤醒线程。否则下一次park方法调用保证不被阻塞。如果线程没有被开启,该方法不保证有任何影响。

public static void unpark(Thread thread) {    if (thread != null)        unsafe.unpark(thread);}

返回最后一次park方法调用,并且未调用unpark方法的线程返回的blocker。如果未被阻塞,则返回null。返回的值 只是内存快照。线程也许已经被其他的blocker 操作了unblocked或者blocked操作。

public static Object getBlocker(Thread t) {    if (t == null)        throw new NullPointerException();    return unsafe.getObjectVolatile(t, parkBlockerOffset);}

除非允许,否则失效所有现有线程的调度操作。 如果允许操作,那么马上处理并返回。否则现有线程将变成不可调度直到以下三种情况发生: 1、一切其他线程以该线程为目标调用了unpark方法。 2、其他线程打断了该线程。 3、伪造调用返回

public static void park() {    unsafe.park(false, 0L);}

转载于:https://my.oschina.net/zjItLife/blog/668046

你可能感兴趣的文章
移动端fixed后 横竖屏切换时上部或下部出现空隙问题
查看>>
Django ORM 操作 必知必会13条 单表查询
查看>>
selenium 安装与 chromedriver安装
查看>>
ethereumjs/ethereumjs-vm-1-简介
查看>>
go标准库的学习-fmt
查看>>
iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接)
查看>>
Java集合框架中的快速失败(fail—fast)机制
查看>>
特殊的上下文选择符
查看>>
iphone-common-codes-ccteam源代码 CCUIApplication.m
查看>>
展开和折叠GridView行
查看>>
SharePoint PeopleEditor 控件的使用
查看>>
删除mysql__转
查看>>
python+selenium的使用
查看>>
python2.7中MySQLdb的安装与使用详解
查看>>
知乎技术方案初探[转]
查看>>
Java中的Thread与Runnable的区别
查看>>
2018/11/29 一个64位操作系统的设计与实现 02 (安装nasm)
查看>>
python(48):re.split 多分隔符
查看>>
nyoj746 整数划分(四)
查看>>
FZU 1894 志愿者选拔 单调队列
查看>>