一直对同步代码块和notify()不是很熟悉,后来做了个教程,总算是了解清楚了。
wait(),notify()和notifyAll() 其实是用于线程间的通信的。
Java有一个内建的等待机制来允许线程在等待信号的时候变为非运行状态。java.lang.Object 类定义了三个方法,wait()、notify()和notifyAll()来实现这个等待机制。
一个线程一旦调用了任意对象的wait()方法,就会变为非运行状态,直到另一个线程调用了同一个对象的notify()方法。为了调用wait()或者notify(),
线程必须先获得那个对象的锁。也就是说,线程必须在同步块里调用wait()或者notify()。
package io.study.example;
public class WaitAndNotify {
class MonitorObject {
}
class TestThread1 implements Runnable {
WaitNotifyObject object;
TestThread1(WaitNotifyObject obj) {
this.object = obj;
}
@Override
public void run() {
this.object.doWait();
}
}
class TestThread2 implements Runnable {
WaitNotifyObject object;
TestThread2(WaitNotifyObject obj) {
this.object = obj;
}
@Override
public void run() {
this.object.doNotify();
}
}
class WaitNotifyObject {
MonitorObject myMonitorObject = new MonitorObject();
boolean wasSignalled = false; //避免假唤醒的情况
public void doWait() {
synchronized (myMonitorObject) {
while(!wasSignalled){
try {
System.out.println("WaitNotifyObject wait!!");
// 一个线程一旦调用了任意对象的wait()方法,就会变为非运行状态,直到另一个线程调用了同一个对象的notify()方法
myMonitorObject.wait();
//唤醒后会继续从wait()地方开始执行
System.out.println("WaitNotifyObject wait over!!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
wasSignalled = true;
}
}
public void doNotify() {
synchronized (myMonitorObject) {
wasSignalled = true;
System.out.println("WaitNotifyObject notify!!");
myMonitorObject.notify();
}
}
}
public static void main(String[] args) throws InterruptedException {
WaitAndNotify test = new WaitAndNotify();
WaitNotifyObject obj = test.new WaitNotifyObject();
Thread t1 = new Thread(test.new TestThread1(obj));
Thread t2 = new Thread(test.new TestThread2(obj));
t1.start();
Thread.sleep(1000);
t2.start();
//synchronized(this) 表示监控调用方方法的本身
}
}
其中看到代码中有一个wasSignalled变量。
这个变量用于阻止线程假启动的情况。