且看下面一段不加锁的代码:
public class WaitTest3 {
public static void main(String[] args) {
final String obj = "xx";
final Thread t1 = new Thread("t1") {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 开始执行");
System.out.println(Thread.currentThread().getName() + " 执行完毕,开始notify");
obj.notify();
}
};
Thread t2 = new Thread("t2") {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 开始wait");
System.out.println(Thread.currentThread().getName() + " 开始wait 1s");
obj.wait();
System.out.println(Thread.currentThread().getName() + " 已经被唤醒执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t2.start();
t1.start();
}
}
暂且忽略java.lang.IllegalMonitorStateException异常,如果这里面不加锁,t2和t1同时执行,那么可能会造成再t2准备wait的时候,t1这时候已经执行完了notify,那么当t2 wait之后,就再也不能被唤醒。,加锁是为了,同步线程状态,通过同步机制,确保线程从wait方法返回时候,能够感知到到notify线程对变量做出的修改。