驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
Java重读基础系列:synchronized 小记
/  

Java重读基础系列:synchronized 小记

翻看之前笔记,临时总结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. 问题1:为什么需要 synchronized(lock)
    复杂的解释有很多,其实有一个简单的理解就是,线程wait后需要进入一个等待队列,更专业的说法叫做wait set。其他线程必须要知道唤醒那个wait set中的线程集合了。所以说lock绑定了等待集合。

  2. 问题2: lock.notifyAll()是调用后立刻执行释放锁的操作吗?
    不是的,代码中有一个睡眠的代码,通过控制台运行可以看出,a 重新工作是延迟了一定的睡眠时间的。所以写代码的时候,一定要注意此处,要不然很容易出现问题,最好是 notifyAll 后面就没有业务代码了!

积土成山,风雨兴焉。积水成渊,蛟龙生焉。