【多线程】java多线程实现生产者消费者模式

 

 思考问题:

1.为什么用wait()+notify()实现生产者消费者模式?

wait()方法可以暂停线程,并释放对象锁
notify()方法可以唤醒需要该对象锁的其他线程,并在执行完后续步骤,到了synchronized临界区后,才会把锁释放

 

2.为什么wait()、notify()、notifyAll()方法需要放在同步代码块中执行?

wait()方法暂停线程执行,并立即释放对象锁

notify()/notifyAll() 方法唤醒其他等待该对象锁的线程,并在执行完同步代码块中的后续步骤后,释放对象锁

notify()和notifyAll()的区别在于:
    notify只会唤醒其中一个线程,
    notifyAll则会唤醒全部线程。
    
至于notify会唤醒哪个线程,是由线程调度器决定的。

 

因为这三个方法都需要获取到对象锁才能有效执行。否则就会抛异常:java.lang.IllegalMonitorStateException

 

3.wait()是暂停的哪个线程?notify()唤醒的是哪个线程?

wait()是暂停当前线程。

notify()则是唤醒等待当前对象锁的线程

 

4.什么是生产者消费者模式

一个产数据,一个用数据,中间最多再加上个存取仓库

 

生产者消费者模式 就是java多线程通信一个很好的例子

 

5.生产着消费者模式特点是什么

1.解耦,生产者干生产者的事情,消费者干消费者的事情

2.支持高并发,可以同时多个生成,多个消费,互不影响

 

 

 

 

 

一对一的生产者消费者模式:

 

早餐类:

package com.sxd.swapping.test.ProducerAndConsumerTest;

/**
 * 早餐基础类
 *
 * wait()
 * notify()
 * notifyAll()
 * 三个方法 需要放在同步代码块中执行 因为要获取对象锁
 */
public class Breakfast{
    private  String food;

    private  String drink;

    private boolean flag = false;//flag = false 表示需要生产  flag = true 表示需要消费

    public synchronized  void  makeBreakfast(String food,String drink){

        System.out.println("生产者进入--->标志值为:"+flag);
        if (flag){
            try {
                System.out.println("make---wait()暂停,释放对象锁");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.food = food;
        try {
            System.out.println("make---sleep()休眠,不释放对象锁");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        this.drink = drink;
        System.out.println("make---生产者制造东西完成----");
        this.flag = true;
        System.out.println("make---notify()唤醒,标志值为"+flag);
        notify();
    }


    public synchronized void eatBreakfast(){

        System.out.println("消费者进入--->标志值为:"+flag);
        if(!flag){
            try {
                System.out.println("eat---wait()");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        try {
            System.out.println("eat---sleep()");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("吃东西---"+this.food+";喝东西---"+this.drink);
        this.flag = false;
        System.out.println("eat---notify()唤醒,标志值为"+flag);
        notify();
    }
}
View Code

 生产者类:

package com.sxd.swapping.test.ProducerAndConsumerTest;

public class Producer implements Runnable{

    private Breakfast breakfast;

    public Producer(Breakfast breakfast) {
        this.breakfast = breakfast;
    }

    @Override
    public void run() {
        int i = 7;
        for (int i1 = 0; i1 < i; i1++) {
            if (i1 %2 == 0){
                this.breakfast.makeBreakfast("馒头","豆浆");
            }else {
                this.breakfast.makeBreakfast("面包","冷饮");
            }
        }
    }
}
View Code

消费者类:

package com.sxd.swapping.test.ProducerAndConsumerTest;

public class Consumer implements Runnable{

    private Breakfast breakfast;

    public Consumer(Breakfast breakfast) {
        this.breakfast = breakfast;
    }

    @Override
    public void run() {
        int i = 7;
        for (int i1 = 0; i1 < i; i1++) {
            System.out.println("星期"+(i1+1)+"---消费者要来吃东西了");
            this.breakfast.eatBreakfast();
        }
    }
}
View Code

 

线程启动主测试类:

package com.sxd.swapping.test.ProducerAndConsumerTest;

public class Test {

    public static void main(String[] args) {
        Breakfast breakfast = new Breakfast();
        new Thread(new Producer(breakfast)).start();
        new Thread(new Consumer(breakfast)).start();
    }
}
View Code

 

展示结果:

 

转载于:https://www.cnblogs.com/sxdcgaq8080/p/10654201.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值