谈谈Object对象的wait和notify

大家都知道java中的object对象除了hashcode equals这些方法外,还有非常重要的两个方法就是wait和notify

wait 等待

notify 唤醒

先看现象 再做推导和结论 如下所示

上图直接运行会报异常 如下所示

上面异常百度会搜索很多答案出来 我来简单概括一下

一个对象要想用wait方法 则调用wait方法的这个对象所处的线程必须持有这个对象的锁,  即synchronized(object)

如下图所示

但是这样主线程一直在等待之中   "已经醒来"是不会被打印的 那么如何让已经醒来也打印呢 这个时候notify方法就派上用场了

A线程wait   B线程notify通知A线程醒来 如下图所示

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("线程A等待获取lock锁");
        synchronized (lock) {
            try {
                System.out.println("线程A获取了lock锁");
                Thread.sleep(1000);
                System.out.println("线程A将要运行lock.wait()方法进行等待");
                lock.wait();
                System.out.println("线程A等待结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}).start();

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("线程B等待获取lock锁");
        synchronized (lock) {
            System.out.println("线程B获取了lock锁");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程B将要运行lock.notify()方法进行通知");
            lock.notify();
        }
    }
}).start();

线程A等待获取lock锁
线程A获取了lock锁
线程B等待获取lock锁
线程A将要运行lock.wait()方法进行等待
线程B获取了lock锁
线程B将要运行lock.notify()方法进行通知
线程A等待结束

从上面打印结果来看   的确线程B执行了lock.notify方法以后  处于wait状态的线程A又执行了wait方法之后的代码

从上面的结果也说明了一个结果 处于wait状态以后线程A自动释放了锁,不然线程B是不会执行synchronized的方法的。

那么重头戏来了,接下来的这个思考方式我相信整个搜索引擎都没有提到过,上面只有一个线程等待一个线程唤醒的情况

那么如果此时再来一个线程等待的话 线程B会唤醒哪一个线程呢

如下所示 加入线程C等待

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("线程C等待获取lock锁");
        synchronized (lock) {
            System.out.println("线程C获取了lock锁");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程C将要运行lock.wait()方法进行等待");
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程C等待结束");
        }
    }
}).start();

  你们可以试一下 无论执行多少次 都是谁最先等待  最先唤醒谁 而且另外一个会一直处于等待中

那么有什么方法可以全部唤醒等待线程呢  很简单notifyall方法可以 但是前提是这个唤醒线程 必须最后执行 可以里面加个线程休眠时间设置长一点

我的博客就是这样 不讲概念 只讲现象 让你自己去感悟 涨知识的话加个关注

 

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值