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

wait 等待

notify 唤醒

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

谈谈Object对象的wait和notify

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

谈谈Object对象的wait和notify

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

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

如下图所示

谈谈Object对象的wait和notify

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

谈谈Object对象的wait和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();

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

谈谈Object对象的wait和notify

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

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

 

 

 

 

 

 

相关文章: