生产者和消费者

107 阅读1分钟

「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

编写代码模拟常见的生产者消费者问题

package com.lemon;

public class Lesson2_Producter {
    public static void main(String[] args) {
        AirConditioner airConditioner = new AirConditioner();
        new Thread(()->{
            for (int i = 0; i <100 ; i++) {
                try {
                    airConditioner.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

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

        },"A").start();
    }
}
class AirConditioner{
    private int num=0;
    public  synchronized void  increment() throws InterruptedException {
        if(num!=0){
            this.wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName()+"             num="+num);
        this.notifyAll();//通知其他线程
    }
    public synchronized void decrement() throws InterruptedException {
        if(num!=1){
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName()+"              num="+num);
        this.notifyAll();
    }

}

1.高聚合低内聚前提下,线程操作资源类

2.判断/干活/通知

3.多线程交互中,必须要防止多线程的虚假唤醒

多线程交互中不能用if必须用while

虚假唤醒

像在一个参数版本中,中断和虚假唤醒是可能的,并且该方法应该始终在循环中使用: 

  synchronized (obj) {
         while (<condition does not hold>)
             obj.wait();
         ... // Perform action appropriate to condition
     } 该方法只能由作为该对象的监视器的所有者的线程调用。 有关线程可以成为监视器所有者的方式的说明,请参阅notify方法。 

买票的程序没有交互

蛋糕店卖蛋糕有需求才制作

wait释放锁,sleep不释放锁

使用while替代if防止虚假唤醒

package com.lemon;

public class Lesson2_Producter {
    public static void main(String[] args) {
        AirConditioner airConditioner = new AirConditioner();
        new Thread(()->{
            for (int i = 0; i <100 ; i++) {
                try {
                    airConditioner.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"B").start();
        new Thread(()->{
            for (int i = 0; i <100 ; i++) {
                try {
                    airConditioner.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
​
        },"A").start();
        new Thread(()->{
            for (int i = 0; i <100 ; i++) {
                try {
                    airConditioner.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();
        //线程D
        new Thread(()->{
            for (int i = 0; i <100 ; i++) {
                try {
                    airConditioner.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();
    }
}
class AirConditioner{
    private int num=0;
    public  synchronized void  increment() throws InterruptedException {
        while(num!=0){
            this.wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName()+"             num="+num);
        this.notifyAll();//通知其他线程
    }
    public synchronized void decrement() throws InterruptedException {
        while(num!=1){
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName()+"              num="+num);
        this.notifyAll();
    }
​
}

等待时间越长优先级越高