栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

notify和notifyAll的区别,notify死锁问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

notify和notifyAll的区别,notify死锁问题

具体讲解参照博客区别
下面补充一个例子,来说明,使用notify会产生死锁,但是使用notifyAll不会。

原题为lleetcode 1195

大体意思是:四个线程,调用同一个对象的四个不同方法,然后实现线程的同步。

在这里使用了synchornized和state来实现这个题目。
下面分析一种情况说明notify会产生死锁,而notifyAll会。

修改完state = 0后,使用notify激活了应该执行state = 3的线程A。
然后,线程state = 0, 调用了wait方法,锁死了自己。
此时,锁队列上,挂了四个线程,虽然此时的锁已经释放了,但是没有外部的干预,四个线程都没有回到竞争队列上面的时候。
这就出现了有锁,但是无法执行的状态。
但是这并不是操作系统意义上面的死锁。因为不满足死锁的四个状态。

package leetcode;

import java.util.function.IntConsumer;



public class FizzBuzz3 extends FizzBuzz{
    // 使用synchornize + state的方式来实现
    private int state = 0;     // 0 : 数字, 1 :fizz, 2:buzz, 3
    private Object obj = new Object();
    private int n;

    public FizzBuzz3(int n) {
        super(n);
        this.n = n;
    }
    // printFizz.run() outputs "fizz".
    public void fizz(Runnable printFizz) throws InterruptedException {
        for (int i = 3; i <= n; i += 3) {
            if (i % 5 == 0) continue;
            synchronized (obj) {
                while (state != 1) {
                    obj.wait();
                }
                printFizz.run();
                state = 0;
                obj.notifyAll();
            }
        }
    }

    // printBuzz.run() outputs "buzz".
    public void buzz(Runnable printBuzz) throws InterruptedException {
        for (int i = 5; i <= n; i += 5) {
            if (i % 3 == 0) continue;       // 如果不行,就不该状态,否则最后一个可能输出不了
            synchronized (obj) {
                while (state != 2) {
                    obj.wait();
                }
                printBuzz.run();
                state = 0;
                obj.notifyAll();       // 可能会死锁,如果都wait就死锁了。
            }
        }
    }

    // printFizzBuzz.run() outputs "fizzbuzz".
    public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
        for (int i = 15; i <= n; i += 15) {     // 只要等于3,就可以直接输出了
            synchronized (obj) {
                while (state != 3) {
                    obj.wait();
                }
//                System.out.println("nstate = " + state + " i = " + i);
                printFizzBuzz.run();
                state = 0;          // 只有输出才有资格改,否则自己也能竞争
                obj.notifyAll();
            }
        }
    }

    // printNumber.accept(x) outputs "x", where x is an integer.
    public void number(IntConsumer printNumber) throws InterruptedException {
        for (int i = 1; i <= n; i++) {
            synchronized (obj) {
                while (state != 0) {
                    obj.wait();
                }
                if (i % 3 != 0 && i % 5 != 0) {
                    printNumber.accept(i);
                } else {
                    if (i % 3 == 0 && i % 5 == 0) {
                        state = 3;
                    } else if (i % 5 == 0) {
                        state = 2;
                    } else state = 1;
                }
//                System.out.println(" state = " + state);
                obj.notifyAll();
            }
        }
    }

    public static void main(String[] args) throws Exception{
        String[] className = {"leetcode.FizzBuzz3", "20"};
        FuzzBuzzMain.main(className);
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/881256.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号