多线程-线程间通信-多生产者多消费者示例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程-线程间通信-多生产者多消费者示例相关的知识,希望对你有一定的参考价值。
1.多线程-线程间通信-多生产者多消费者问题
多生产者和多消费者。等待唤醒机制。
产生了两个问题:
1.出现了多次连续生产,未消费,或者一个商品被消费多次。
解决:必须要--------每一个被唤醒的线程判断一次标记,所以将if判断改为while判断。
2.出现了死锁。
本方唤醒了本方,导致了所有的线程都等待了。
解决方式就是:唤醒所有等待的线程。这样既唤醒了本方也唤醒对方。
虽然解决了多生产消费的问题,但是有些低效。
解决方法一: 唤醒所有等待的线程
class Resource{ private String name;//定义一个商品都有名字。 private int count = 1; //定义一个商品的编号。 private boolean flag = false;//定义用来判断是否有商品的标记。 public synchronized void set(String name){ while(flag) try{wait();}catch(Exception e){}//t1,t2 this.name = name+"--"+count;//蛋糕1 蛋糕2 蛋糕3 count++; System.out.println(Thread.currentThread().getName()+"---生产了,"+this.name); //生产蛋糕1 生产蛋糕2 生产蛋糕3 flag = true; //将标记改为true。 notifyAll();//唤醒等待的线程。 } public synchronized void get()//{ while(!flag) try{wait();}catch(Exception e){}//t3.t4 System.out.println(Thread.currentThread().getName()+"-------消费了....."+this.name);//消费蛋糕1 flag = false; notifyAll(); } } //定义生产者的任务。 class Producer implements Runnable{ private Resource r; Producer(Resource r){ this.r = r; } public void run(){ while(true){ r.set("蛋糕"); } } } //定义消费者的任务。 class Consumer implements Runnable{ private Resource r; Consumer(Resource r){ this.r = r; } public void run(){ while(true){ r.get(); } } } class ThreadDemo_Producer_Consumer2 { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); //创建两个生产者线程。 Thread t1 = new Thread(pro); Thread t2 = new Thread(pro); //创建两个消费者线程。 Thread t3 = new Thread(con); Thread t4 = new Thread(con); t1.start(); t2.start(); t3.start(); t4.start(); } }
解决方法二:使用Lock锁对象和Condition监听对象
根据jdk1.5 版本的特性,创建一个锁对象。比同步的隐式锁操作要更加的面向对象。提供了显示的锁操作。
通过lock锁获取监视器方法对象。Condition 负责生产者的监视操作。
再创建一个监视器方法对象。负责消费者的监视操作。
解决了低效的问题
import java.util.concurrent.locks.*; class Resource{ //定义一个商品都有名字。 private String name; //定义一个商品的编号。 private int count = 1; //定义用来判断是否有商品的标记。 private boolean flag = false; //根据jdk1.5 版本的特性,创建一个锁对象。比同步的隐式锁操作要更加的面向对象。提供了显示的锁操作。 final Lock lock = new ReentrantLock();//互斥锁。 //通过lock锁获取监视器方法对象。Condition 负责生产者的监视操作。 final Condition producer = lock.newCondition(); //再创建一个监视器方法对象。负责消费者的监视操作。 final Condition consumer = lock.newCondition(); public void set(String name)//{ //通过锁对象进行显示的获取锁操作。 lock.lock();//获取锁,锁的开始位置,想从哪里锁就把锁放在什么地方 try{ while(flag) try{producer.await();}catch(Exception e){}//t1,t2 this.name = name+"--"+count; count++; System.out.println(Thread.currentThread().getName()+"生产了,"+this.name); //将标记改为true。 flag = true; consumer.signal();//唤醒等待的线程。 }finally{ //释放锁。 lock.unlock();//定义在finally中,要求一定被释放。 } } public void get()//{ lock.lock(); try{ while(!flag) try{consumer.await();}catch(Exception e){}//t3.t4 System.out.println(Thread.currentThread().getName()+"--消费了."+this.name); //消费蛋糕1 flag = false; producer.signal(); }finally{ lock.unlock(); } } } //定义生产者的任务。 class Producer implements Runnable{ private Resource r; Producer(Resource r){ this.r = r; } public void run(){ while(true){ r.set("蛋糕"); } } } //定义消费者的任务。 class Consumer implements Runnable{ private Resource r; Consumer(Resource r){ this.r = r; } public void run(){ while(true){ r.get(); } } } class ThreadDemo_Producer_Consumer3 { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); //创建两个生产者线程。 Thread t1 = new Thread(pro); Thread t2 = new Thread(pro); //创建两个消费者线程。 Thread t3 = new Thread(con); Thread t4 = new Thread(con); t1.start(); t2.start(); t3.start(); t4.start(); } }
以上是关于多线程-线程间通信-多生产者多消费者示例的主要内容,如果未能解决你的问题,请参考以下文章
JAVA-初步认识-第十四章-线程间通信-多生产者多消费者问题-JDK1.5新特性解决办法-范例