wait/notify
wait()方法的作用就是将当前执行代码的线程进行等待,wait()方法时Object类的方法用来将当前线程置入 “预执行队列” 中,在wait()方法所在的代码行处停止执行,直到收到通知或者中断为止。
notify()方法的作用就是将多个等待线程,由线程规划期随机挑选出其中一个wait状态的线程,发出notify唤醒。
- wait/notify方法调用前,需要先获取对象锁
public class Test {
public static void main(String[] args) {
try {
Object obj = new Object();
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果:
[Console output redirected to file:D:\console.txt]
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at cn.spy.thread.test.Test.main(Test.java:8)
- 等待唤醒例子
public class MyThread1 extends Thread {
private Object lock;
public MyThread1(Object lock) {
this.lock = lock;
}
@Override
public void run() {
try {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " start wait " + System.currentTimeMillis());
lock.wait();
System.out.println(Thread.currentThread().getName() + " end wait " + System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread2 extends Thread {
private Object lock;
public MyThread2(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " start notify " + System.currentTimeMillis());
lock.notify();
System.out.println(Thread.currentThread().getName() + " end notify " + System.currentTimeMillis());
}
}
}
public class Test {
public static void main(String[] args) {
try {
Object lock = new Object();
MyThread1 mt1 = new MyThread1(lock);
mt1.setName("MyThread1");
mt1.start();
Thread.sleep(5000);
MyThread2 mt2 = new MyThread2(lock);
mt2.setName("MyThread2");
mt2.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果:
[Console output redirected to file:D:\console.txt]
MyThread1 start wait 1541050962125
MyThread2 start notify 1541050967127
MyThread2 end notify 1541050967127
MyThread1 end wait 1541050967127
说明:可以发现MyThread2在执行notify方法唤醒MyThread1,然后MyThread2没有马上释放线程,MyThread1没有马上获取线程。
① 等待通知的执行顺序是如果我们执行了notify();方法并不会马上就释放线程了,而那个wait状态的线程也不能马上获取该对象锁。得等到notify();方法的线程执行完(也就是退出了synchronized代码块后),线程才会释放锁,而呈wait(); 状态的线程才可以获取该对象锁。
② 当前如果有多个线程处于等待的状态,那么使用notify();方法,线程规划器只会随机的挑选出其中一个线程。
③ wait方法执行后,锁自动释放,但是执行完notify方法,锁不会自动释放。
总结
- wait/notify方法调用前,需要先获取对象锁
- notify唤醒多个等待线程,是随机挑选出的。
- wait方法执行后,锁自动释放,但是执行完notify方法,锁不会自动释放。
- notify唤醒的线程不会马上执行(因为notify方法的执行,锁不会自动释放)。
- 当线程呈wait();状态时,调用线程对象的interrupt();方法会报一个InterruptedException异常。
网友评论