`

LockSupport 源码阅读

 
阅读更多

在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这个类:

 

    // Hotspot implementation via intrinsics API
    private static final Unsafe unsafe = Unsafe.getUnsafe();  //unsafe 用来实现底层操作
    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) {

 

下面写些代码试下

 

    	System.out.println("start");
    	LockSupport.parkNanos(1000000000);
    	System.out.println("end");
    	//一开始会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就积累

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0
1
分享到:
评论
1 楼 QuarterLifeForJava 2015-08-11  
貌似不止一个,CyclicBarrier cb = new CyclicBarrier(3);
CyclicBarrier也是

相关推荐

    Java并发编程学习之Unsafe类与LockSupport类源码详析

    《深入解析Java并发编程:Unsafe类与LockSupport类源码剖析》 在Java并发编程领域,Unsafe类和LockSupport类是两个重要的底层工具类,它们提供了低级别的内存操作和线程控制,使得开发者能够实现高效的并发算法和...

    源码解析文件ScheduledThreadPoolExecutor

    源码解析文件ScheduledThreadPoolExecutor 在 Java 中,ScheduledThreadPoolExecutor 是一个线程池执行器,用于执行延迟任务。它使用DelayedWorkQueue来实现延迟的效果。下面是 ScheduledThreadPoolExecutor 的实现...

    基于JDK源码解析Java领域中的并发锁之设计与实现.pdf

    本文将基于JDK源码解析Java领域中的并发锁,探讨AQS基础同步器、LockSupport、Condition接口、Lock接口、ReadWriteLock接口以及自定义API操作的设计与实现。 一、AQS(AbstractQueuedSynchronizer)基础同步器的...

    Java并发包源码分析(JDK1.8)

    Java并发包源码分析(JDK1.8):囊括了java.util.concurrent包中大部分类的源码分析,其中涉及automic包,locks包(AbstractQueuedSynchronizer、ReentrantLock、ReentrantReadWriteLock、LockSupport等),queue...

    java+多线程+同步详解Java源码

    在深入理解多线程和同步机制时,阅读和分析JDK源码是很有帮助的。例如,研究`Thread`类、`synchronized`关键字的实现、`LockSupport`类等,可以帮助我们更好地理解Java的并发机制。 综上所述,Java的多线程和同步...

    java7并发编程实战手册+源码

    5. **锁的优化**:Java 7引入了弱引用锁(LockSupport.park/unpark),以及自旋锁和可中断锁的优化,使得锁的实现更加灵活和高效。ReentrantLock、ReadWriteLock等接口和类提供了高级锁定机制。 6. **并发工具类**...

    openjdk-analyze:jdk源码分析

    通过源码分析,我们可以看到如`LockSupport`、`ForkJoinPool`等是如何工作的。 6. 字符串处理:`java.lang.String`是Java中至关重要的类,OpenJDK源码揭示了字符串的创建、比较、拼接等操作的内部实现,这对于理解...

    disruptor-translation:Disruptor原始代码分解析出(超详细注释),版本3.4.2,方便大家阅读源码,供大家学习使用。项目中使用时请从Disruptor官方发布依赖。注释也可能存在一些不太到位的地方,可能是理解偏差,欢迎指正

    Disruptor原始代码分解析出(超详细注释),版本3.4.2,方便大家阅读源码,供大家学习使用。项目中使用时请从Disruptor官方发布依赖。 ,欢迎指正。 LMAX破坏者 高性能线程间消息传递库 维护者 文献资料 变更日志 ...

    java Thread

    - 同步代码块:使用`synchronized`关键字包裹代码块,锁定特定对象,控制并发访问。 - `wait()`和`notify()`/`notifyAll()`:用于线程间的通信,需在同步环境中使用。 - `ReentrantLock`:可重入锁,提供更灵活的...

    Java并发编程之Condition源码分析(推荐)

    LockSupport.park(this); //判断是否被中断 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } //获取锁,如果获取中被中断则设置中断状态 if (acquireQueued(node, savedState) && ...

    java-concurrency-in-practice:java并发精讲

    4. 等待(Waiting):线程在等待其他线程执行特定操作(如wait()、join()或LockSupport.park())。 5. 定时等待(Timed Waiting):线程在等待一段时间后自动恢复(如Thread.sleep()、Object.wait(long)等)。 6. ...

    【2018最新最详细】并发多线程教程

    18.一篇文章,从源码深入详解ThreadLocal内存泄漏问题 19.并发容器之BlockingQueue 20.并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解 21.线程池ThreadPoolExecutor实现原理 22.线程池之...

    Java 多线程 设计模式

    在Java编程中,多线程是一项关键特性,它允许程序同时执行多个任务,极大地提高了...《Java 多线程设计模式》一书的源代码应该涵盖了这些知识点的具体实现,通过阅读和实践,可以深入理解多线程编程和设计模式的精髓。

    精心整理的AQS和JUC相关的面试题.pdf【ReentrantLock】

    ⼀、ReentrantLock重⼊锁 1.1> 概述 1.2> 中断响应 lockInterruptibly() 1.3> 锁申请等待限时 tryLock(long time, TimeUnit unit) 1.4> 公平锁和⾮公平锁 1.5> AQS源码解析 ...七、LockSupport线程阻塞⼯具类

    [bugfix]重新理解Thread的InterruptedException

    这样做的目的是确保后续代码可以检测到中断请求,特别是对于那些依赖于中断状态的高阶并发工具(如`ExecutorService`,`Future`等)。 下面是一段典型的处理`InterruptedException`的代码示例: ```java try { ...

    java7hashmap源码-to-be-architect:成为Java架构师,你应该学习这些

    hashmap源码 to-be-architect to be a Java architect,you should learn these.This page is updated irregularly. Java基础 深入分析 Java SPI 机制和原理 并发编程专题 Executors线程池 线程池ThreadPoolExecutor...

    对java的BitSet的多线程并发的探索

    同时,阅读BitSet的源码也是理解其工作原理和潜在问题的关键,这有助于我们更好地利用和优化BitSet在多线程环境下的使用。 最后,文章中可能还介绍了通过博客链接(https://huangyunbin.iteye.com/blog/2194731)...

    java技术指南

    对于并发编程,文档详细讨论了java.util.concurrent包下的各种并发工具类和接口,如LockSupport、AbstractQueuedSynchronizer、各种锁的实现(ReentrantLock、ReentrantReadWriteLock、StampedLock等)、并发集合...

    如何聪明地使用锁

    - 使用`LockSupport.park()`和`LockSupport.unpark()`来精细化控制线程的阻塞和唤醒。 - 尽可能使用无锁编程(如原子变量、并发容器等)和并发工具类,减少锁的使用。 在实际开发中,聪明地使用锁意味着要根据...

Global site tag (gtag.js) - Google Analytics