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

Java 多线程 唤醒中的 虚假唤醒

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

Java 多线程 唤醒中的 虚假唤醒

这里写目录标题
    • synchronized 版本,双线程,生产者消费者
      • 运行结果
    • synchronized 版本,四线程, 生产者消费者
      • 运行结果
        • 这里,居然,卡住了,不知道为啥
    • synchronized 版本,四线程, 生产者消费者,使用 while 判断
      • 运行结果
        • 总结
      • 参考目录

synchronized 版本,双线程,生产者消费者
public class 虚假唤醒 {

    public static void main(String[] args) {
        Data data=new Data();
        new Thread(()->{
            for (int i=0;i<10;i++)
             try {
                data.increment();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();


        new Thread(()->{
            for (int i=0;i<10;i++)
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        },"A").start();
    }




}

//判断等待,业务,通知
class Data{  //数字 资源类

    private int number=0;

    //+1
    public synchronized void increment() throws InterruptedException {
        if (number!=0){  //0
            //等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread()+"=>"+number);
        //通知其他线程,我+1完毕了
        this.notifyAll();
    }
    //-1
    public synchronized void decrement() throws InterruptedException {
        if (number==0){  //1
            //等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread()+"=>"+number);
        //通知其他线程,我-1完毕了
        this.notifyAll();
    }


}
运行结果

synchronized 版本,四线程, 生产者消费者
public class 虚假唤醒 {

    public static void main(String[] args) {
        Data data=new Data();
        new Thread(()->{
            for (int i=0;i<10;i++)
             try {
                data.increment();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();


        new Thread(()->{
            for (int i=0;i<10;i++)
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        },"A").start();

        new Thread(()->{
            for (int i=0;i<10;i++)
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        },"C").start();


        new Thread(()->{
            for (int i=0;i<10;i++)
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        },"D").start();

    }




}

//判断等待,业务,通知
class Data{  //数字 资源类

    private int number=0;

    //+1
    public synchronized void increment() throws InterruptedException {
        if (number!=0){  //0
            //等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread()+"=>"+number);
        //通知其他线程,我+1完毕了
        this.notifyAll();
    }
    //-1
    public synchronized void decrement() throws InterruptedException {
        if (number==0){  //1
            //等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread()+"=>"+number);
        //通知其他线程,我-1完毕了
        this.notifyAll();
    }


}
运行结果

这里,居然,卡住了,不知道为啥 synchronized 版本,四线程, 生产者消费者,使用 while 判断
public class 虚假唤醒 {

    public static void main(String[] args) {
        Data data=new Data();
        new Thread(()->{
            for (int i=0;i<10;i++)
             try {
                data.increment();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();


        new Thread(()->{
            for (int i=0;i<10;i++)
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        },"A").start();

        new Thread(()->{
            for (int i=0;i<10;i++)
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        },"C").start();


        new Thread(()->{
            for (int i=0;i<10;i++)
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        },"D").start();

    }




}

//判断等待,业务,通知
class Data{  //数字 资源类

    private int number=0;

    //+1
    public synchronized void increment() throws InterruptedException {
        while (number!=0){  //0
            //等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread()+"=>"+number);
        //通知其他线程,我+1完毕了
        this.notifyAll();
    }
    //-1
    public synchronized void decrement() throws InterruptedException {
        while (number==0){  //1
            //等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread()+"=>"+number);
        //通知其他线程,我-1完毕了
        this.notifyAll();
    }


}
运行结果

总结

可以看出,在需要判断来进行 Wait() 的情况下,不要使用 if 的一次判断,最好使用 while 的循环判断。

因为,当一个 线程,因为 if 判断符合,而进入 if 来 Wait() 后,只要有 线程 notifyAll() 来唤醒这个线程时,就不会再次进行 if 判断,从而 逃脱 条件判断。因为 wait notify后,会从 wait 的地方 继续执行。而 while 可以 防止这种情况的发生。

参考目录

狂神
https://www.bilibili.com/video/BV1B7411L7tE?p=7&spm_id_from=pageDriver

说的比较详细的 博客
https://blog.csdn.net/qq_39455116/article/details/87101633

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

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

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