• 线程死锁情况和while在线程的作用


    public class printDemo04 {
        public static void main(String[] args) {
            Resource01 resource01 = new Resource01();
            Producer producer = new Producer(resource01);
            Producers  producers = new Producers(resource01);
            Thread thread0 = new Thread(producer);
            Thread thread1 = new Thread(producer);
            Thread thread2 = new Thread(producers);
            Thread thread3 = new Thread(producers);
            thread0.start();
            thread1.start();
            thread2.start();
            thread3.start();
        }
    }
    class Resource01{
        private String name;
        private int sex = 1;
        private boolean flag = false;
        public synchronized void setSth(String name){
            while(flag){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.name = name+sex;
            sex++;
            System.out.println(Thread.currentThread().getName()+"----"+"生产者..."+this.name);
            flag = true;
            this.notifyAll();
        }
        
        public synchronized void getSth(){
            while(!flag){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+"--"+"消费者..."+name);
            flag = false;
            this.notifyAll();
        }
    }
    class Producer implements Runnable{
        Resource01 resource01;
        public Producer(Resource01 resource01) {
            this.resource01 = resource01;
        }
        int i = 1;
        @Override
        public void run() {
            while(true){
                if(i==1){
                    resource01.setSth("烤鸭");
                }
                i = (i+1)%2;
            }
        }
    }
    class Producers implements Runnable{
        Resource01 resource01;
        public Producers(Resource01 resource01) {
            this.resource01 = resource01;
        }
        
        @Override
        public void run() {
            while(true){
                resource01.getSth();
            }
        }
    }

      死锁发生的情况:上述代码中,把标色的this.notifyAll();改为this.notify();就会发生线程的死锁,为什么呢?应为代码中总共有4个线程,生产者1和生产者2,消费者1和消费者2。理想状态是生产者1和生产者2执行生产操作,消费者1和消费者2执行消费操作,生产一个,消费一个。现在线程进入首先执行生产操作,打个比方生产1生产了烤鸭1,然后flag等于true,如果接下来执行的生产操作的话,这个生产线程就会被等待,这时候执行的生产者2,就会被等待,接下来执行消费者2线程消费者2线程执行完以后flag为false,这时候有要选择一个线程执行,因为生产者2在线程池中被等待,所以现在只能执行生产者1、消费者1和消费者2,假设这时候执行生产者1又生产了烤鸭2,然后又在前面三个线程中选择了生产者1,这时候flag为true,生产者1又进入了线程池进行了等待。然后线程只有2个可以执行消费者1和消费者2,这时候消费完以后,flag为false,接下来只能执行消费线程,但是没法生产flag就只能为false,所以这时候消费者1和消费者2就都会被等待,到此为止,4个线程都被等待,于是就发生了死锁。使用notifyAll()就不会发生死锁了。

      while在这的作用是判断当前执行的线程是否应该被执行,就像代码中所表示的执行完生产只能消费。

  • 相关阅读:
    封了1000多个IP地址段,服务器现在坚如磐石,对付几个小毛贼还是很轻松的
    这两周服务器被攻击,封锁了600多个IP地址段后今天服务器安静多了
    centos clamav杀毒软件安装配置及查杀,没想到linux下病毒比windows还多!
    JS 在页面上直接将json数据导出到excel,支持chrome,edge,IE10+,IE9,IE8,Safari,Firefox
    一个实战系统的权限架构思维推导过程
    股灾情形下搞了个满堂红,我也是醉了
    VBC#代码互转工具
    DSAPI多功能.NET函数库组件
    DS标签控件文本解析格式
    DSAPI官方QQ群
  • 原文地址:https://www.cnblogs.com/hongcong/p/5875997.html
Copyright © 2020-2023  润新知