Java多线程之基于Synchronized的等待唤醒-03
文章目录
一、wait()、notify()、notifyAll()概述
在Object.java中,定义了wait(), notify()和notifyAll()等接口。wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。而notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是随机唤醒单个线程,而notifyAll()是唤醒所有的等待线程。
Object类中关于等待/唤醒的API详细信息如下:
notify()– 唤醒在此对象监视器上等待的单个线程。
notifyAll() – 唤醒在此对象监视器上等待的所有线程。
wait() – 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒(进入“就绪状态”)。
wait(long timeout) – 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量”,当前线程被唤醒(进入“就绪状态”)。
wait(long timeout, int nanos)– 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量”,当前线程被唤醒(进入“就绪状态”)。
好了,接下来就开始讲解wait()、notify()、notifyAll()。
二、基于synchronized
接下来就讲解这三者的作用、使用、原理。
1、作用与原理
synchronized关键字用于保护共享数据,阻止其他线程对共享数据的存取,但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出synchronized数据块时让其他线程也有机会访问共享数据呢?此时就用这三个方法来灵活控制。
- wait()方法使当前线程暂停执行并释放对象锁标示,让其他线程可以进入synchronized数据块,当前线程被放入对象等待池中。
- 当调用notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。
- notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。
2、使用
它们都是Object麾下的三名士兵。
为什么说是Object下的三名士兵呢?是因为三者都是Object类的方法,正是因为如此:
-
它们必须是由同步监视器(也就是syncrynized包围的那个对象)来调用, 用于协调多个线程对共享数据的存取。如果不是由同步对象来调用,则会抛出 java.lang.IllegalMonitorStateException异常。
就像:
synchronized (waitAndNotifyThread) {
try {
System.out.println(Thread.currentThread().getName()+" start t1");
waitAndNotifyThread.start();
// 主线程等待t1通过notify()唤醒。
System.out.println(Thread.currentThread().getN`ame()+" wait()");
//这里会抛出异常
Thread.currentThread()

本文介绍了Java中基于Synchronized的等待唤醒机制,包括wait(), notify(), notifyAll()的使用和原理。wait()会让当前线程等待并释放锁,notify()随机唤醒一个等待线程,notifyAll()唤醒所有等待线程。这些方法必须在同步块中由共享对象调用,否则会抛出异常。通过示例展示了它们在多线程操作共享资源时的应用。"
110187613,10172503,OmniGraffle Pro for Mac:专业图表绘制工具,"['图形设计', '绘图工具', '流程图软件', 'Mac应用', '数据可视化']
最低0.47元/天 解锁文章
7494

被折叠的 条评论
为什么被折叠?



