• Synchronized 的wait 和notify


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

    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();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

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

    总结

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

  • 相关阅读:
    适用于4×4MiMo 4G/5G,支持GNSS和WiFi 6E的车载天线解决方案
    毅速丨模具3D打印材料有哪些选择
    [Spring笔记] Spring-32-AOP切入点表达式
    html5期末大作业 基于HTML+CSS制作dr钻戒官网5个页面 企业网站制作
    使用bloodyAD对域属性进行查询与修改
    【初学者入门C语言】之编译预处理(十)
    DDR3 功能测试记录
    【生成对抗网络 论文泛读】……StarganV1 & StarganV2……
    对卷积的一点具象化理解
    【数据结构与算法】图的基本结构介绍 | 邻接表与邻接矩阵编码实战
  • 原文地址:https://blog.csdn.net/weixin_39808420/article/details/134022366