结果:
线程1等待获取 对象A的锁...线程1获取了 对象A的锁线程2等待获取 对象A的锁...线程1开始运行wait()方法进行等待 , 进入到等待队列......线程2获取了 对象A的锁线程2将要运行notify()方法进行唤醒线程1线程1等待结束需要注意的是 , wait/notify/notifyAll 只能在synchronized修饰的方法、块中使用 , notify 是只随机唤醒一个线程 , 而 notifyAll 是唤醒所有等待队列中的线程
joinThread类中的join方法的主要作用能让线程之间的并行执行变为串行执行 , 当前线程等该加入该线程后面 , 等待该线程终止
public static void main(String[] args) {Thread thread = new Thread();thread.start();thread.join();...}上面一个例子表示 , 程序在main主线程中调用thread线程的join方法,意味着main线程放弃CPU时间片(主线程会变成 WAITING 状态) , 并返回thread线程 , 继续执行直到线程thread执行完毕 , 换句话说在主线程执行过程中 , 插入thread线程 , 还得等thread线程执行完后 , 才轮到主线程继续执行
如果查看JDKthread.join()底层实现 , 会发现其实内部封装了wait(),notifyAll()
park/unparkLockSupport.park() 挂起当前线程;LockSupport.unpark(暂停线程对象) 恢复某个线程
package com.zj.ideaprojects.demo.test3;import java.util.concurrent.Executors;import java.util.concurrent.locks.LockSupport;public class ThreadLockSupportTest {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {System.out.println("start.....");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("park....");LockSupport.park();System.out.println("resume.....");});thread.start();Thread.sleep(3000);System.out.println("unpark....");LockSupport.unpark(thread);}}结果:
start.....park....unpark....resume.....当程序调用LockSupport.park() , 会让当前线程A的线程状态会从 RUNNABLE 变成 WAITING , 然后main主线程调用LockSupport.unpark(thread) , 让指定的线程即线程A,从 WAITING 回到 RUNNABLE。我们可以发现 park/unpark和wait/notify/notifyAll很像 , 但是他们有以下的区别:
- wait , notify 和 notifyAll 必须事先获取对象锁 , 而 unpark 不必
- park、unpark 可以先 unpark ,而 wait、notify 不能先 notify , 必须先wait
- unpark 可以精准唤醒某一个确定的线程 。而 notify 只能随机唤醒一个等待线程 , notifyAll 是唤醒所以等待线程 , 就不那么精确
这部分比较简单 , 它和线程等待状态(WAITING)状态 非常相似 , 区别就是方法的参数舒服传入限制时间 , 在 Timed Waiting状态时会等待超时 , 之后由系统唤醒 , 或者也可以提前被通知唤醒如 notify
相关方法主要有:
1. Object.wait(long)2. Thread.join(long) 3. LockSupport.parkNanos(long)4. LockSupport.parkUntil(long)5. Thread.sleep(long)需要注意的是Thread.sleep(long),当线程执行sleep方法时 , 不会释放当前的锁(如果当前线程进入了同步锁) , 也不会让出CPU 。sleep(long)可以用指定时间使它自动唤醒过来 , 如果时间不到只能调用interrupt方法强行打断 。参考资料:
https://hg.openjdk.java.net/jdk8u 《并发编程的艺术》 https://www.jianshu.com/p/216a41352fd8
推荐阅读
- 冻虾变黑了还能吃吗
- 发型|以前的女演员是真敬业,扮丑扮到亲妈不认!哪像现在这么“敷衍”
- 陈意涵|黄晓明锤上加锤,怒揭陈意涵“双面玉女”骗局,原来杨颖真没说谎!
- 如何在夏季来临之时减掉大肚腩,最好还能拥有马甲线?
- 陈意涵|黄晓明锤上加锤,怒揭陈意涵“双面玉女”骗局,原来杨颖真没说谎
- 蜂蜜保质期一般为多长时间 蜂蜜放了五年还能吃吗
- 大米生虫还能吃吗 大米生虫子处理诀窍
- 江疏影|这一次,江疏影被扒了个底朝天!网友:没想到这么乱!
- 张静初|黄晓明锤上加锤,怒揭陈意涵“双面玉女”骗局,原来杨颖真没说谎
- ella|Ella陈嘉桦“还没这么女过”文案翻车,上次被骂道歉的还是白鹿
