目录

Wait()方法是否会释放对象锁之外的锁?

今天看并发的时候,看的调用**wait() 方法会释放了锁,释放的是对象锁。**

有人现在就要问了,啥是对象锁,其实就是对象作为锁的条件。

复制代码
final Object lock = new Object();

synchronized (lock){
                    //同步代码块
            }

上述就是一个对象锁。

wait()方法是否会自动释放锁?

继续看,然后我就去做了一个小测试,看看调用wait方法,会不会释放对象锁。

这里让线程1拿到对象锁,再开始休眠;再让线程2去拿对象锁。

如果线程2拿到对象锁,代表wait方法会自动释放所拿到的对象锁。

复制代码
final Object lock = new Object();
        String resource = "resource";
        new Thread(()->{
            while (true){
                synchronized (lock){
                    System.out.println(Thread.currentThread().getName()+"获取到对象锁");
                    try {
                        lock.wait();
                        System.out.println(Thread.currentThread().getName() + "开始沉睡");
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                try {
                    Thread.sleep(3000); //休眠3s
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
        new Thread(()->{
            while (true){
                synchronized (lock){
                    System.out.println(Thread.currentThread().getName()+"唤醒所以锁");
                    lock.notifyAll();
                }
                try {
                    Thread.sleep(3000); //休眠3s
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();

运行结果如下:还真会自动释放锁。

问题提出,会不会释放在wait方法之外的所有锁呢?

使用wait()方法会不会释放拿到的所有锁?

所以我让线程1先去拿到资源,再去拿对象锁,然后再休眠,看看线程2是否能拿到资源,如果拿到代表wait方法可以释放所有拿到的锁;如果没拿到,代表只能释放当前拿到的对象锁。

复制代码
final Object lock = new Object();
        String resource = "resource";

        new Thread(() -> {
            while (true) {
                synchronized (resource){
                    System.out.println(Thread.currentThread().getName() +"获取到了资源");
                    synchronized (lock){
                        lock.notify();
                        System.out.println(Thread.currentThread().getName() +"去唤醒任意线程");
                        System.out.println(Thread.currentThread().getName() + "获取对象锁");
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                        System.out.println(Thread.currentThread().getName()+"开始沉睡");

                    }
                }
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println();
            }
        }, "线程 1").start();

        new Thread(() -> {
            while (true) {
                synchronized (resource){
                    System.out.println(Thread.currentThread().getName() +"获取到资源");
                }
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println();
            }
        }, "线程 2").start();

结果如下:wait方法并不能释放拿到的所有锁,只会释放拿到的当前的对象锁。

好吧,这只是一个无聊的测试。。。。。主要是问GPT时候,它告诉了我错误答案,所以才测试了。

通过上述案例,我们再思考一个问题,

为什么wait方法不放在Thread类中,为什么放在Object类中?

wait() 是让获得对象锁的线程实现等待,会自动释放当前线程占有的对象锁。每个对象(Object)都拥有对象锁,既然要释放当前线程占有的对象锁并让其进入 WAITING 状态,自然是要操作对应的对象(Object)而非当前的线程(Thread)。

类似问题如下:

为什么 sleep() 方法定义在 Thread

因为 sleep() 是让当前线程暂停执行,不涉及到对象类,也不需要获得对象锁。

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
Tracy-223 小时前
啥是Spring,有什么用,既然收费,如何免费创建SpringBoot项目,依赖下载不下来的解决方法,解决99%问题!
java·spring
未定义.2214 小时前
Java设计模式实战:策略模式在SimUDuck问题中的应用
java·设计模式·策略模式
HelloRevit4 小时前
Next.js 快速启动模板
开发语言·javascript·ecmascript
码熔burning6 小时前
【NIO番外篇】之组件 Channel
java·nio·channel
卡尔曼的BD SLAMer6 小时前
问题 | 针对SSM(Spring + Spring MVC + MyBatis)框架的去Spring MVC强化版学习路线
java·spring·mvc·mybatis
春生野草6 小时前
0413-多态、Object类方法、访问权限修饰符、装箱拆箱、128陷阱
java·开发语言
烁3477 小时前
每日一题(小白)暴力娱乐篇25
java·数据结构·算法·娱乐
烁3477 小时前
每日一题(小白)暴力娱乐篇26
java·开发语言·算法·娱乐
周周记笔记7 小时前
探索R语言:在线学习资源汇总
开发语言·r语言
zuoming1207 小时前
c# 系列pdf转图片 各种处理3--net3.1到net8 PDFtoImage
开发语言·pdf·c#