27/365 java 生产者-消费者

1.实际应用场景:生产者-消费者问题

 分析:

2.线程通信

 3.用线程通信来解决生产者-消费者问题

  • 管程法
  • 信号灯法

4.管程法

 

具体代码如下:

public class D24 {
    public static void main(String[] args) {
        Basket basket = new Basket();
        new Producer(basket).start();
        new Consumer(basket).start();
    }
}

class Bread {
    int id;

    public Bread(int id) {
        this.id = id;
    }
}

class Basket{
    Bread[] bread = new Bread[8];
    int num = 0;
    public synchronized void push(Bread b){
        while(num >= bread.length){
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        bread[num++] = b;
        this.notifyAll();



    }

    public synchronized Bread pop(){
        while(num<=0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
            Bread b2 = bread[--num];
            this.notifyAll();
            return b2;




    }
}

class Producer extends Thread{
    Basket basket;
    Producer(Basket basket){
        this.basket = basket;
    }
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            basket.push(new Bread(i));
            System.out.println("push bread " + i);
        }
    }
}

class Consumer extends Thread{
    Basket basket;

    Consumer(Basket basket){
        this.basket = basket;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("pop bread " + basket.pop().id);
        }
    }
}

当缓冲区已满时,生产者应当wait()

当缓冲区为空时,消费者应当wait()

当生产者向缓冲区成功放入产品后,应notifyAll()来通知正在等待的消费者。

当消费者向缓冲区成功取走产品后,应notifyAll()来通知正在等待的生产者。

wait()方法

使当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法。

当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后线程等待,直到它可以重新获得监视器的所有权并继续执行。

使用格式:

 5.信号灯法

用一个标志位来表示资源是否可用

没有缓冲区,所以资源最多只有一份

public class D25 {

    public static void main(String[] args) {
        Dish dish = new Dish();
        new Cooker(dish).start();
        new Customer(dish).start();
    }
}

class Cooker extends  Thread{
    Dish dish;

    Cooker(Dish dish){
        this.dish = dish;
    }

    @Override
    public void run() {
        for (int i = 0; i < 15; i++) {
            if(i%2==0)
                dish.cook("Fired Chicken");
            else
                dish.cook("Beef");
        }
    }
}

class Customer extends Thread{
    Dish dish;

    Customer(Dish dish){
        this.dish = dish;
    }

    @Override
    public void run() {
        for (int i = 0; i < 15; i++) {
            dish.eat();
        }
    }
}

class Dish{
    String name;
    boolean flag = false;

    synchronized void  cook(String name){
        while(flag){
            try {
                wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        this.name = name;
        flag = !flag;
        System.out.println(Thread.currentThread().getName() + " cook " + name);
        notifyAll();
    }

    synchronized void eat(){
        while(!flag){
            try {
                wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        flag = !flag;
        System.out.println(Thread.currentThread().getName() + " eat " + name);
        notifyAll();
    }
}

结果:线程协作

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值