Synchronized 的wait 和notify

news/2024/5/17 16:39:44 标签: 1024程序员节, Synchronized, wait, notify

synchronized 是java里面的一个关键字,用来保证原子性,这是大家都知道的,还有synchronized是对对象进行加锁的,wait方法会释放锁,然后等待,notify唤醒等待的线程,sleep 睡眠不会释放锁,好,这些都是大家已经知道的

wait__notify_1">wait notify方法到底是怎么使用的

wait方法和notify都必须在持有锁的时候进行调用,简单找个使用场景,三个线程顺序打印ABC

@Test
    public void testSynchronized(){
        Object lock = new Object();
        int ans[] = new int[]{0};
        new Thread(()->{
            while (true){
                synchronized(lock){
                    try {
                        while (ans[0]%3!=0){
                            lock.wait();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ans[0]++;
                    System.out.println("A");
                    lock.notifyAll();
                }
            }
        }).start();
        new Thread(()->{
            while (true){
                synchronized(lock){

                    try {
                        while (ans[0]%3!=1){
                            lock.wait();
                        }

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ans[0]++;
                    System.out.println("B");
                    lock.notifyAll();
                }
            }
        }).start();
        new Thread(()->{
            while (true){
                synchronized(lock){
                    try {
                        while (ans[0]%3!=2){
                            lock.wait();
                        }

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ans[0]++;
                    System.out.println("C");
                    lock.notifyAll();
                }
            }
        }).start();


        try {
            // 阻塞主线程
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

这是使用synchronized来进行实现的,简单来说就是加锁,锁住之后判断当前应该哪个进行执行,该执行的进行执行,不该执行的就进行wait释放对应的锁,这里执行wait之后就释放了锁,后面就不在执行,但是代码位置还是在这里,所以必须使用while,if会带来什么问题呢,就是if判断之后当前释放锁,然后wait,但是等下一个notifyAll的时候,这里就不再从上面走if语句判断了,直接走下面的修改数据然后打印,就造成了数据的错误,还有个问题就是notifynotify的问题,这里本线程执行之后,应该使用notify还是notifyAll呢,这里的差别就是唤醒一个还是唤醒多个的问题,因为wait之后就进行等待队列等待唤醒,notify就是唤醒一个,notifyAll唤醒全部,这里就需要使用notifyALl,需要全部唤醒,因为唤醒一个的话,可能当前线程并不是要执行的线程,这里就需要都唤醒,然后根据对应的数字来取模来进行判断该哪个线程执行

总结

这里需要注意的点就是当前wait之后,代码块执行的位置记录不会改变,下次唤醒之后,获取到锁的话,直接执行,不会重新走上面判断,
wait需要在持有锁的时候使用,notifynotifyAll也是


http://www.niftyadmin.cn/n/5118894.html

相关文章

Text Classification via Large Language Models

Abstract 表达大模型在文本分类上做的不好。 原因: 1、处理复杂语境时缺少推理能力。(e.g… 类比、讽刺) 2、限制学习的上下文的token数。 提出了自己的策略: ** Clue And Reasoning Prompting (CARP).线索与推理提示** 1、能用prompt找到clue(语境线索…

NeRF综述

文章目录 《Nerf: Neural radiance field in 3d vision, a comprehensive review 》一、数据集:二、基于方法的分类(Method-based Taxonomy)三、基于应用的分类(Application-based Taxonomy)四、未来展望 《Nerf: Neur…

力扣刷题 day54:10-24

1.十进制整数的反码 每个非负整数 N 都有其二进制表示。例如, 5 可以被表示为二进制 "101",11 可以用二进制 "1011" 表示,依此类推。注意,除 N 0 外,任何二进制表示中都不含前导零。 二进制的反…

什么是脚本文件,脚本的执行,脚本格式等

1.脚本文件是什么? 脚本文件是包含一系列计算机命令的文本文件,通常用于自动化任务、自定义功能或执行特定操作。这些命令通常按照一定的编程语法和语义规则编写,以便计算机能够逐行解释和执行它们。脚本文件通常包含了一组操作,…

CSS设置超出范围滚动条和滚动条样式

CSS设置超出范围滚动条和滚动条样式 效果展示 当块级内容区域超出块级元素范围的时候,就会以滚动条的形式展示,你可以滚动里面的内容,里面的内容不会超出块级区域范围。 未设置超出隐藏,显示滚动条 超出隐藏,显示滚动…

【学习笔记】CF1784F Minimums or Medians

首先让 n n n乘上 2 2 2。 考虑枚举最终被删除的位置有哪些。 a i 0 a_i0 ai​0表示这个位置被删除, a i 1 a_i1 ai​1表示这个位置被保留,设满足 a i 0 a_i0 ai​0的前缀长度为 l l l( l l l是偶数), p r e i pre…

alibaba.fastjson的使用(四)-- Json字符 与 JsonObject 的相互转化

目录 1. Json字符串转JsonObject 2. JsonObject转Json字符串 1. Json字符串转JsonObject 使用到的方法1: static JSONObject parseObject(String text) 使用到的方法2: public String getString(String key) /*** 将Json字符串转为JsonObject对象* 取值不存在时,返回null…

字符串划分

题目描述 给定一个小写字母组成的字符串s,请找出字符串中两个不同位置的字符作为分割点,使得字符串分成的三个连续子串且子串权重相等,注意子串不包含分割点。 若能找到满足条件的两个分割点,请输出这两个分割点在字符串中的位置…