一、notify()
作用:唤醒一个正在等待该线程的锁的线程
PS : 唤醒的线程不会立即执行,它会与其他线程一起,争夺资源
/** * Object类的notify()和notifyAll()方法详解 */ public class MyNotify { // 在多线程间共享的对象上使用wait private String[] shareObj = {"true"}; public static void main(String[] args) { MyNotify test = new MyNotify(); //创建3个等待线程 ThreadWait threadWait1 = test.new ThreadWait("线程1"); ThreadWait threadWait2 = test.new ThreadWait("线程2"); ThreadWait threadWait3 = test.new ThreadWait("线程3"); //创建一个解放线程对象,用于通知等待线程运行 ThreadNotify threadNotify = test.new ThreadNotify("释放线程"); //等待线程启动,在释放线程把锁释放之后,争夺运行的机会 threadWait1.start(); threadWait2.start(); threadWait3.start(); //释放线程启动,sleep3秒后释放线程 threadNotify.start(); } /** * 线程等待类 */ class ThreadWait extends Thread { //调用父类构造方法设置线程名称 public ThreadWait(String name) { super(name); } public void run() { synchronized (shareObj) { while ("true".equals(shareObj[0])) { System.out.println("线程" + this.getName() + "开始等待"); long startTime = System.currentTimeMillis(); try { shareObj.wait();//无尽等待,直至notify()或者notifyAll() } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.println("线程" + this.getName() + "等待时间为:" + (endTime - startTime)); } } System.out.println("线程" + getName() + "等待结束"); } } /** * 线程释放类 */ class ThreadNotify extends Thread { //调用父类构造方法设置线程名称 public ThreadNotify(String name) { super(name); } public void run() { try { // 给等待线程等待时间 sleep(3000);//此时sleep方法会获取对象锁,其他线程处于等待并获取锁的状态 } catch (InterruptedException e) { e.printStackTrace(); } synchronized (shareObj) { System.out.println(this.getName() + "开始准备通知"); shareObj[0] = "false"; shareObj.notify();//解放一个正在等待的线程(随机) // shareObj.notifyAll();//解放所有等待的线程 System.out.println(this.getName() + "通知结束"); } System.out.println(this.getName() + "运行结束"); } } }
详见这里~
二、notifyAll()
作用:唤醒所有正在等待该线程的锁的线程
PS:并不一定会按线程优先级来执行
三、wait()
作用:导致当前的线程进入无尽等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法
四、wait(long timeout)
作用:导致当前的线程等待,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者指定的时间过完。
五、wait(long timeout, int nanos)
作用:类似于wait(long timeout)方法,更精准,附加时间在毫微秒范围0-999999。
六、常见异常
- IllegalArgumentException -- 如果超时的值是负的或毫微秒的值不在0-999999范围内。
- IllegalMonitorStateException -- 如果当前线程不是对象监视器的拥有者。
- InterruptedException -- 如果另一个线程中断了当前线程。当这种异常被抛出当前线程的中断状态被清除。