我在网上看到很多人错误的理解,认为wait不会释放锁,然而它们并没有任何理由,仅凭自己的认知,然后很骄傲的和人讲,wait不会释放锁,你这是误人子弟。殊不知他自己才是误人子弟。


我先讲一讲原理,然后用代码来证明它,让那些还认为wait不会释放锁的同志闭嘴。赶紧改错还来的及

原理

其实很好理解,从设计的角度很容易分析出wait是会释放锁的。

线程在运行的时候占用了计算机的共享资源,因为当前线程在使用它,然而当前线程进行了休眠例如 wait() 很浅显的道理,当前线程已经停止了,那意味着这个资源空闲了下来。那么作为万恶的剥削者"程序员"肯定不会让这个资源空闲着,你们说对吧!!!

因此很容易推断出wait()是会释放锁的,而锁的奥义就是控制指定的线程持有共享资源,既然线程都进行了等待,肯定是要需要释放锁的!!!


贴代码前我先讲一下怎么用代码进行证明
很简单,用两个线程同时用一把锁,其中一个线程先执行,并且进行wait(),如果释放了锁,那么是不是对于另外一个线程来说它就可以抢占到这个锁呢(因为它空闲下来了)

而我的代码中为了让两个线程实现这种效果,我让一个线程等待一秒

代码

import java.util.concurrent.TimeUnit;

public class Demo {

    public static void main(String[] args) {
        Object object=new Object();

        final Thread thread1 = new Thread(() -> {
            System.out.println("线程1开始");
            synchronized (object) {
                try {
                    object.wait();// 进行阻塞,并且释放对象锁
                    System.out.println("====线程1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程1结束");
        });

        final Thread thread2 = new Thread(() -> {
            System.out.println("线程2开始");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (object){
                System.out.println("线程2=======");
            }
            System.out.println("线程2结束");
        });
        thread1.start();
        thread2.start();
    }
}

运行结果
wait会释放锁?当然会释放锁,代码见真招!!!_对象锁
从结果中很明显发现 wait()方法会让当前线程释放锁,而线程2等了1s后,因为线程1释放了锁,因此线程2就能抢占到。


继续证明线程2的synchronized (object)在没有获取锁的情况下是会阻塞等待锁释放

代码2

import java.util.concurrent.TimeUnit;

public class Demo {

    public static void main(String[] args) {
        Object object=new Object();

        final Thread thread1 = new Thread(() -> {
            System.out.println("线程1开始");
            synchronized (object) {
                try {
                    TimeUnit.SECONDS.sleep(2000); // 等待足够长时间让我们足以观察到结果
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("====线程1");
  
            }
            System.out.println("线程1结束");
        });

        final Thread thread2 = new Thread(() -> {
            System.out.println("线程2开始");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (object){
                System.out.println("线程2=======");// 输出这一句说明当前线程抢占到了锁
            }
            System.out.println("线程2结束");
        });
        thread1.start();
        thread2.start();
    }

}

wait会释放锁?当然会释放锁,代码见真招!!!_JAVA_02