LockSupport 源码阅读
  TEZNKK3IfmPf 2023年11月14日 13 0

在java中,要让线程等待最普通的方法是调用Object.wait()方法,

Causes the current thread to wait until another thread invokes the notify() method for this object.

但是当我阅读JUC(java.util.concurrent)的源码时发现这个包不是这样做的, 我跟踪CountDownLatch.await()调用,最后跟到了LockSupport.park()方法里, 这里调用的是 unsafe.park()方法来block线程。

LockSupport 和 CAS一样是JUC很多控制机制的基础(但他们的底层其实都是在依赖Unsafe),下面就来学习下LockSupport这个类:

<br/> // Hotspot implementation via intrinsics API<br/> private static final Unsafe unsafe = Unsafe.getUnsafe(); //unsafe 用来实现底层操作<br/> private static final long parkBlockerOffset; //辅助参数,配合unsafe用的

//This object is recorded while

// the thread is blocked to permit monitoring and diagnostic tools to

// identify the reasons that threads are blocked.

//设置一个线程和关联的blocker对象,blocker用来做分析,debug用的

private static void setBlocker(Thread t, Object arg) {

// Even though volatile, hotspot doesn’t need a write barrier here.

unsafe.putObject(t, parkBlockerOffset, arg);

}

//block当前线程,是否真的block了取决于permit是否available

//permit相当于1,0的开关, 默认是0, 调一次unpark就+1变成1了,调一次park会消费这个1又变成0了(park立即返回),

//再次调用park会变成block(因为没有1可以拿了,会等在这,直到有1),这时调用unpark会把1给回去(线程解锁返回)

//每个线程都有个相关的permit, permit最多一个,调用unpark多次也不会积累

//当为permit available时,方法会立即返回,不会block,反之就会block当前线程直到下面3件事发生

//1. 其他线程调用了unpark(此线程)

//2. 其他线程interrupts了此线程

//3. The call spuriously (that is, for no reason) returns.

public static void park() {

unsafe.park(false, 0L);

}

//对于给定线程,让permit变得avaliable,

public static void unpark(Thread thread) {

if (thread != null)

unsafe.unpark(thread);

}

//然后park有2个带限定时间的版本,所以一共有3个park version, 这3个version又有带blocker的debug版本

public static void parkNanos(long nanos) {

public static void parkUntil(long deadline) {

下面写些代码试下

<br/> System.out.println("start");<br/> LockSupport.parkNanos(1000000000);<br/> System.out.println("end");<br/> //一开始会block线程,直到给定时间过去后才往下走

System.out.println(“start”);

LockSupport.unpark(Thread.currentThread());

LockSupport.parkNanos(1000000000);

System.out.println(“end”);

//不会block,因为一开始给了一个permit

System.out.println(“start”);

LockSupport.unpark(Thread.currentThread());

LockSupport.unpark(Thread.currentThread());

LockSupport.parkNanos(1000000000);

System.out.println(“inter”);

LockSupport.parkNanos(1000000000);

System.out.println(“end”);

//第一个park不会block,第2个会,因为permit不会因为多次调用unpark就积累

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月14日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   2023年11月15日   36   0   0 多线程同步
  TEZNKK3IfmPf   2023年11月15日   39   0   0 多线程同步
  TEZNKK3IfmPf   2023年11月15日   20   0   0 多线程同步
  TEZNKK3IfmPf   2023年11月15日   23   0   0 多线程同步
TEZNKK3IfmPf