java中使用阻塞队列解决生产者消费者问题
来源:互联网 发布:淘宝裸根月季苗 编辑:程序博客网 时间:2024/06/06 19:46
java语言中提供了blockingQueue阻塞队列以及几种实现:
在解决多线程生产者,消费者问题的时候,可以使用阻塞队列来代替java同步原语wati()和notify()以及sychronized。简化编程模型。
下面使用linkedBlockingQueue来简化生产者消费者问题[1]。
问题:有一台机器有三个任务,一个制作toast,一个抹黄油,一个涂果酱,还有一个消费toast的人,总共有四个任务,使用队列解决这四个任务之间的协同?
解决方法描述如下图:
- make线程制作toast之后put到dryQueue
- butterer线程从dryQueue队列take获得toast,处理之后放入butteredQueue队列
- jammer线程从butteredQueue队列take获得toast,处理之后放入finnishedQueue队列
阻塞队列take方法在队列为空时阻塞,直到队列中有元素为止。使用阻塞队列处理的好处就是:在程序中可以不使用任何显示的同步以及wait()/notify()等方法。
1,toast类
使用枚举类型描述toast的状态
/** * 枚举类 * @author lecky * */public class Toast { public enum Status {DRY,BUTTER,JAMMED} private Status status = Status.DRY; private final int id; public Toast(int id) { super(); this.id = id; } public void butter(){ status = Status.BUTTER; } public void jammer(){ status = Status.JAMMED; } public int getId() { return id; } public Status getStatus() { return status; } @Override public String toString() { return "Toast [status=" + status + ", id=" + id + "]"; }}
2,Toaster类
import java.util.concurrent.BlockingQueue;/** * 制作面包线程 * 只与dryQueue阻塞队列交互,做完面包之后就交给dryQueue队列 * @author lecky * */public class Toaster implements Runnable{ private BlockingQueue<Toast> dryQueue; private int count=0; public Toaster(BlockingQueue<Toast> dryQueue) { this.dryQueue = dryQueue; } @Override public void run() { try { while (!Thread.interrupted()) { Thread.sleep(1000);//制作toast Toast t = new Toast(++count); dryQueue.put(t); System.out.println("toaster make the toast!"+t); } } catch (InterruptedException e) { System.out.println("Toaster InterruptedException"); } System.out.println("Toaster OK!"); }}
3,Butterer类
import java.util.concurrent.BlockingQueue;/** * 抹黄油线程 * 从dryQueue队列获得任务,并抹黄油之后交给butterQueue队列 * @author lecky * */public class Butterer implements Runnable{ private BlockingQueue<Toast> dryQueue; private BlockingQueue<Toast> butterQueue; public Butterer(BlockingQueue<Toast> dryQueue, BlockingQueue<Toast> butterQueue) { this.dryQueue = dryQueue; this.butterQueue = butterQueue; } @Override public void run() { try { while (!Thread.interrupted()) { Toast t = dryQueue.take(); System.out.println("Butterer Take The Toast and buttering........"+t); t.butter(); Thread.sleep(500);//butterer过程 butterQueue.put(t); } } catch (InterruptedException e) { System.out.println("Butter InterruptedException"); } System.out.println("butterer Off!"); }}
4,Jammer类
import java.util.concurrent.BlockingQueue;/** * 涂果酱任务 * 从butterQueue队列获取任务并涂上果酱,交给finishedQueue * @author lecky * */public class Jammer implements Runnable{ private BlockingQueue<Toast> butterQueue; private BlockingQueue<Toast> finishedQueue; public Jammer(BlockingQueue<Toast> butterQueue, BlockingQueue<Toast> finishedQueue) { this.butterQueue = butterQueue; this.finishedQueue = finishedQueue; } @Override public void run() { try { while (!Thread.interrupted()) { Toast t = butterQueue.take(); System.out.println("jammer take the toast and jammering......"+t); t.jammer(); Thread.sleep(300); finishedQueue.put(t); } } catch (InterruptedException e) { System.out.println("Jammer InterruptedException"); } System.out.println("Jammer Off!"); }}
5,Eater类
import java.util.Set;import java.util.concurrent.BlockingQueue;/** * 从finishedQueue获取任务并消费任务 * @author lecky * */public class Eater implements Runnable { private BlockingQueue<Toast> finishedQueue; private int counter=0; public Eater(BlockingQueue<Toast> finishedQueue) { this.finishedQueue = finishedQueue; } @Override public void run() { try { while (!Thread.interrupted()){ Toast t = finishedQueue.take(); if(++counter != t.getId() || Toast.Status.JAMMED !=t.getStatus()){ System.out.println("error>>>>"+t); System.exit(0); } System.out.println("eater take the toast and eat...."+t); } } catch (InterruptedException e) { System.out.println("eater InterruptedException"); } System.out.println("eater off!"); }}
6,测试类
import java.util.concurrent.BlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingDeque;import org.junit.After;import org.junit.Before;import org.junit.Test;public class ToastMatic { @Test public void test() throws InterruptedException { ExecutorService executor = Executors.newCachedThreadPool(); BlockingQueue<Toast> dryQueue = new LinkedBlockingDeque<Toast>(); BlockingQueue<Toast> butteredQueue = new LinkedBlockingDeque<Toast>(); BlockingQueue<Toast> finishedQueue = new LinkedBlockingDeque<Toast>(); executor.execute(new Eater(finishedQueue)); executor.execute(new Jammer(butteredQueue, finishedQueue)); executor.execute(new Butterer(dryQueue, butteredQueue)); executor.execute(new Toaster(dryQueue)); Thread.sleep(5*1000); System.out.println("shunDown"); executor.shutdownNow();; }}
[1].Thinking in java
0 0
- java中使用阻塞队列解决生产者消费者问题
- Java多线程之生产者消费者问题<三>:使用阻塞队列更优雅地解决生产者消费者问题
- 关于java用阻塞队列解决生产者消费者问题总结
- java使用阻塞队列实现生产者消费者模式
- 阻塞队列 生产者消费者
- 使用阻塞队列BlockingQueue实现生产者消费者
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 阻塞队列实现生产者消费者
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- Java多线程之生产者消费者问题<一>:使用synchronized 关键字解决生产者消费者问题
- 使用阻塞队列实现生产者-消费者模式——Java实现
- Java生产者-消费者模式的非阻塞队列实现
- 1067. Sort with Swap(0,*) (25)
- 从尾到头打印链表
- 多线程中的锁机制
- JS的'=='、'==='、'!='、'!=='及数字字符串的'-'操作
- XML-DOM
- java中使用阻塞队列解决生产者消费者问题
- LightOJ 1048 - Conquering Keokradong(二分)
- timeout
- 单位关系之随笔
- [OpenGL]第一个OpenGL程序
- 查看用户组的信息
- Android 第三方开源SwipeToDismiss:左滑/右滑删除ListView条目Item
- 模板_KMP算法
- swift析构方法和扩展