Java 多线程之wait/notify的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41723615/article/details/88733633

线程间通信:
1.使用wait/notify实现线程间的通信。
2.生产者/消费者模式的实现
3.方法join的使用
4.ThreadLocal类的使用

一、等待/通知机制
线程与线程之间不是独立的个体,可以相互通信和协作。
1.使用sleep()结合while(true)死循环法来实现多个线程间通信。
wait/notify机制来实现减少CPU的资源浪费,而且还可以实现在多个线程间通信。
多个线程访问同一个变量实现通信,并不是等待/通知机制,这两个线程完全主动式地读取一个共享变量,
在花费读取时间的基础上,读到的值是不是想要的,并不能完全确定。

二、等待/通知机制的实现
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码解析:end在最后输出,也说明notify()方法执行后并不立即释放锁,关键字synchronized可以将任何一个Object对象作为同步对象来看待,而Java为每个object都实现了wait()和notify()方法,它们必须用在被synchronized同步的Object的临界区内。通过调用wait()方法可以使处于临界区的线程加入等待状态,同时释放被同步对象的锁。而notify操作可以唤醒一个因调用了wait操作而处于阻塞状态中的线程,使其加入就绪状态。被重新唤醒的线程会试图重新获取临界区的控制权,也就是锁,并继续执行临界区内wait之后的代码,如果发粗话notify操作时没有处于阻塞状态中的线程,那么命令会被忽略。
wait()方法可以使调该方法的线程释放并共享资源的锁,然后从运行状态退出,进入等待队列,直到被再次唤醒。
notify()方法可以随机唤醒等待队列中等待同一共享资源的一个线程,并使该线程退出等待队列,进入可执行状态,也就是notify()方法仅通知一个线程。

方法解释
方法wait():使当前执行代码的线程进行等待,Object类的方法。
1.该方法用来将当前线程置入预制行队列中,并且在wait()所在的代码行处停止执行,
直到接到通知或被中断为止。
2.在调用wait()之前,线程必须获取该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法。
3.在执行wait()方法后,当前线程释放锁。
4.在从wait()返回前,线程与其他线程竞争重新获取锁。
5.如果调用wait()时没有持有适当的锁,则抛出IllegalMonitorStateException,
它是RuntimeException的一个子类,因此,不需要try-catch语句进行捕捉异常。

方法notify:
1.要在同步方法或同步块中调用,即在调用前,线程也必须获取该对象的对象级别锁。
2.如果调用notify()时没有持有适当的锁,也会抛出IllegalMonitorStateException。
该方法用来通知哪些可能等待该对象的对象锁的其他线程。
3.如果有多个线程等待,则由线程规划器随机挑选出其中一个呈wait状态的线程,对其发出通知notify,
并使他等待获取该对象的对象锁。
4.在执行notify()方法后,当前线程不会马上释放该对象锁,呈wait状态的线程也并不能马上获取对象锁,
要等到执行notify()方法的线程将程序执行完,也就是退出synchronized代码块后,当前线程才会释放锁,
而wait状态所在的线程才可以获取该对象锁。
5.当第一个获得了该对象锁的wait线程运行完毕以后,它会释放掉该对象锁,此时如果该对象没有再次使用notify语句,
则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,还会继续阻塞在wait状态,
直到这个对象发出一个notify或notifyAll。
总结:wait使线程停止运行,而notify使停止的线程继续运行。

方法notifyAll():可以使所有正在等待队列中等待同一共享资源的全部线程从等待状态退出,加入可运行状态,此时
优先级最高的哪个线程最先执行,但也有可能随机执行,要取决于JVM虚拟机的实现。

猜你喜欢

转载自blog.csdn.net/qq_41723615/article/details/88733633