首页 > 编程语言 > 详细

JUC下线程的三种等待唤醒机制

时间:2021-05-24 00:51:29      阅读:33      评论:0      收藏:0      [点我收藏+]

第一种:Object类中的wait和notify方法实现线程的等待和唤醒

技术分享图片

下面标黄字的部分就是对一下两点总结的实现:

  • 不能脱离synchronized代码块使用,否则会抛出IllegalMonitorStateException异常
  • 先wait后notify、notifyAll,等待中的线程才能被唤醒,顺序不能改变

演示代码:

/**
 * @author zhangzhixi
 * @date 2021-5-23 18:21
 */
public class LockDemo {
    static Object object = new Object();

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (object) {
                System.out.println(Thread.currentThread().getName() + "==>线程Come in");
                try {
                    // 使当前线程等待
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "==>线程被唤醒");
            }
        }, "A").start();

        new Thread(() -> {
            synchronized (object) {
                System.out.println(Thread.currentThread().getName() + "==>通知线程");
                // 使当前线程唤醒
                object.notifyAll();
            }
        }, "B").start();
    }
}

我们来看下上面代码的执行结果,看起来很和谐:

技术分享图片

 

 我们来将上面代码动下手脚,注释掉代码标红的内容看下wait/notify脱离了Synchronized会出现什么?

可以看到报了异常,说明wait/notify不能够脱离Synchronized代码块

技术分享图片

 


 

我们再来看一下使线程A暂停三秒会发生什么?

线程B先执行了,没有代码将线程A的wait状态进行唤醒

技术分享图片

第二种:Condition接口中的await和single方法实现线程的等待和唤醒

技术分享图片

  • 必须配合lock()方法使用,否则抛出IllegalMonitorStateException异常
  • 等待唤醒调用顺序不能改变

 代码实现:

public class LockDemo {
    static Object object = new Object();
    // 创建可重入锁
    static Lock lock = new ReentrantLock();
    static Condition condition = lock.newCondition();

    public static void main(String[] args) {
        new Thread(() -> {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "==>线程Come in");
                // 使当前线程等待
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            System.out.println(Thread.currentThread().getName() + "==>线程被唤醒");
        }, "A").start();

        new Thread(() -> {

            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "==>通知线程");
                // 使当前线程唤醒
                condition.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "B").start();
    }
}

看下上面代码的执行结果:

技术分享图片  

 我们来将上面代码动下手脚,注释掉代码标红的内容看下wait/notify脱离了Synchronized会出现什么?

可以看到报了异常,说明wait/notify不能够脱离Synchronized代码块

技术分享图片

 

我们再来看一下使线程A暂停三秒会发生什么?

线程B先执行了,没有代码将线程A的await状态进行唤醒

 技术分享图片

第三种:LockSupport类中的park等待和unpark唤醒

JUC下线程的三种等待唤醒机制

原文:https://www.cnblogs.com/zhangzhixi/p/14802614.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!