java多线程 消费者生产者_【多线程】java多线程实现生产者消费者模式 synchronized+Object的wait/notify方式 和 Lock+Condition的await/s...

=========================使用synchronized,配合Object的wait()/notify()实现生产者消费者======================

思考问题:

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.支持高并发,可以同时多个生成,多个消费,互不影响

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

1>早餐类:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.sxd.swapping.test.ProducerAndConsumerTest;/*** 早餐基础类

*

* wait()

* notify()

* notifyAll()

* 三个方法 需要放在同步代码块中执行 因为要获取对象锁*/

public classBreakfast{privateString food;privateString drink;private boolean flag = false;//flag = false 表示需要生产 flag = true 表示需要消费

public synchronized voidmakeBreakfast(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 voideatBreakfast(){

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

2> 生产者类:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.sxd.swapping.test.ProducerAndConsumerTest;public class Producer implementsRunnable{privateBreakfast breakfast;publicProducer(Breakfast breakfast) {this.breakfast =breakfast;

}

@Overridepublic voidrun() {int i = 7;for (int i1 = 0; i1 < i; i1++) {if (i1 %2 == 0){this.breakfast.makeBreakfast("馒头","豆浆");

}else{this.breakfast.makeBreakfast("面包","冷饮");

}

}

}

}

View Code

3>消费者类:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.sxd.swapping.test.ProducerAndConsumerTest;public class Consumer implementsRunnable{privateBreakfast breakfast;publicConsumer(Breakfast breakfast) {this.breakfast =breakfast;

}

@Overridepublic voidrun() {int i = 7;for (int i1 = 0; i1 < i; i1++) {

System.out.println("星期"+(i1+1)+"---消费者要来吃东西了");this.breakfast.eatBreakfast();

}

}

}

View Code

4>线程启动主测试类:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.sxd.swapping.test.ProducerAndConsumerTest;public classTest {public static voidmain(String[] args) {

Breakfast breakfast= newBreakfast();new Thread(newProducer(breakfast)).start();new Thread(newConsumer(breakfast)).start();

}

}

View Code

5>展示结果:

bff32a5363a2cf65bde3bfb8334d332d.png

===========================使用Lock,配合Condition的await()/signal()实现生产者消费者============================

1.早饭类,提供生产方法和消费方法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.sxd.swapping.test.ProducerAndConsumerTest;importjava.util.LinkedList;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;/***

* Lock配合condition实现生产者消费者模式

*

*@authorsxd

* @date 2019/8/6 9:08*/

public classCondition_Breakfast {private LinkedList breakfastList;//早饭资源容器

private int maxSize;//最大量早饭资源数量 自定义

private Lock lock; //锁

private Condition comsumerCondition;//满条件【即代表消费者等待队列】

private Condition producerCondition;//不满条件【即代表生产者等待队列】//自定义 最大共享资源数量

public Condition_Breakfast(intmaxSize) {this.maxSize =maxSize;

breakfastList= new LinkedList<>();

lock= newReentrantLock();

comsumerCondition=lock.newCondition();

producerCondition=lock.newCondition();

}public voidproduce(String str){

lock.lock();try{while (maxSize ==breakfastList.size()){

System.out.println("如果早餐共享资源已经满足最大量,则进入本方法的当前线程们,进入notFullCondition的等待队列中,线程挂起");

producerCondition.await();

}

breakfastList.add(str);

System.out.println("生产早饭:"+str);

System.out.println("早饭已经被生产了,唤醒消费者等待队列中的线程,可以继续开始消费了");

comsumerCondition.signal();

}catch(InterruptedException e) {

e.printStackTrace();

}finally{

lock.unlock();

}

}publicString consume(){

String str= null;

lock.lock();try{while (breakfastList.size() == 0){

System.out.println("如果早饭共享资源完全==0,就将消费者们挂起,等待生产者生产后再去唤醒消费者们");

comsumerCondition.await();

}

str=breakfastList.poll();

System.out.println("消费早饭:"+str);

System.out.println("早饭已经被消费了,唤醒生产者等待队列中的 线程,可以继续生产了");

producerCondition.signal();

}catch(InterruptedException e) {

e.printStackTrace();

}finally{

lock.unlock();

}returnstr;

}

}

View Code

2.早饭类的生产者

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.sxd.swapping.test.ProducerAndConsumerTest;/***@authorsxd

* @date 2019/8/6 9:26*/

public class Condition_Producer implementsRunnable {

Condition_Breakfast breakfast;publicCondition_Producer(Condition_Breakfast breakfast) {this.breakfast =breakfast;

}

@Overridepublic voidrun() {int i = 7;

String threadName=Thread.currentThread().getName();for (int i1 = 0; i1 < i; i1++) {if (i1 %2 == 0){this.breakfast.produce(threadName+"大馒头"+i1);

}else{this.breakfast.produce(threadName+"大包子"+i1);

}

}

}

}

View Code

3.早饭类的消费者

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.sxd.swapping.test.ProducerAndConsumerTest;/***@authorsxd

* @date 2019/8/6 9:28*/

public class Condition_Comsumer implementsRunnable{

Condition_Breakfast breakfast;publicCondition_Comsumer(Condition_Breakfast breakfast) {this.breakfast =breakfast;

}

@Overridepublic voidrun() {int i = 7;for (int i1 = 0; i1 < i; i1++) {this.breakfast.consume();

}

}

}

View Code

4.测试类

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.sxd.swapping.test.ProducerAndConsumerTest;/***@authorsxd

* @date 2019/8/6 9:30*/

public classTest2 {public static voidmain(String[] args) {

Condition_Breakfast breakfast= new Condition_Breakfast(16);new Thread(newCondition_Producer(breakfast)).start();new Thread(newCondition_Producer(breakfast)).start();new Thread(newCondition_Producer(breakfast)).start();new Thread(newCondition_Comsumer(breakfast)).start();new Thread(newCondition_Comsumer(breakfast)).start();new Thread(newCondition_Comsumer(breakfast)).start();

}

}

View Code

5.启动效果

59d995147549ef7ecf189eb4f22d8027.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值