翻看之前笔记,临时总结2个小知识点。
public class ThreadMain {
private static Object lock = new Object();
public static void main(String[] args) {
new Thread(() -> {
System.out.println("start a");
//lock 需要绑定等待队列
synchronized (lock) {
try {
System.out.println("a get lock");
Thread.sleep(5);
lock.wait();
System.out.println("a release lock");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
System.out.println("start b");
synchronized (lock) {
try {
System.out.println("b get lock");
//notify 不是马上执行,而是等方法执行完成后才执行。
lock.notifyAll();
System.out.println("b release lock");
//此处可以看到明显的阻塞
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
问题1:为什么需要 synchronized(lock)
复杂的解释有很多,其实有一个简单的理解就是,线程wait
后需要进入一个等待队列
,更专业的说法叫做wait set
。其他线程必须要知道唤醒那个wait set
中的线程集合了。所以说lock
绑定了等待集合。
问题2: lock.notifyAll()
是调用后立刻执行释放锁的操作吗?
不是的,代码中有一个睡眠的代码,通过控制台运行可以看出,a 重新工作是延迟了一定的睡眠时间的。所以写代码的时候,一定要注意此处,要不然很容易出现问题,最好是 notifyAll
后面就没有业务代码了!