首页 > 代码库 > 基于java callable及future接口解决生产者消费者问题
基于java callable及future接口解决生产者消费者问题
这两天复习java线程时,把java里面的线程基本知识点与jdk1.5以后新添加的一些类的使用都了解了一下,借用生产者消费者的问题来将他们实践一下。
题目:(题目在csdn一大牛的空间找的)
生产者-消费者模式,这个食堂中只有1张桌子,同时最多放10个盘子,现在有4个厨师做菜,每做好一盘就往桌子上放(生产者将产品往仓库中放),而有6个食客不停地吃(消费者消费产品,为了说明问题,他们的食量是无的).一般而言,厨师200-400ms做出一盘菜,而食客要400-600ms吃完一盘.当桌子上放满了10个盘子后,所有厨师都不能再往桌子上放,而当桌子上没有盘子时,所有的食客都只好等待.
代码如下:
1 package net.xicp.tarbitrary.producerandcustomer; 2 3 import java.util.LinkedList; 4 import java.util.Random; 5 import java.util.concurrent.Callable; 6 import java.util.concurrent.ExecutionException; 7 import java.util.concurrent.ExecutorService; 8 import java.util.concurrent.Executors; 9 import java.util.concurrent.FutureTask; 10 import java.util.concurrent.TimeUnit; 11 import java.util.concurrent.locks.Condition; 12 import java.util.concurrent.locks.Lock; 13 import java.util.concurrent.locks.ReentrantLock; 14 15 16 public class NewFeatureTest { 17 18 public static void main(String[] args) throws InterruptedException, 19 ExecutionException { 20 // 创建一个具有10个线程的线程池 21 ExecutorService se = Executors.newFixedThreadPool(30); 22 // 产生一张桌子,桌子的最大容量为10 23 DiningTable table = new DiningTable(10); 24 // 产生生产者对象 25 Chef chef = new Chef(table); 26 // 产生消费者对象 27 Eater eater = new Eater(table); 28 29 30 //本例只是模拟10个生产者与10个消费者,并没有完全按照题目的意思来进行解答 31 for (int i = 1; i < 11; i++) { 32 final FutureTask cheafTask = new FutureTask(chef); 33 final FutureTask eaterTask = new FutureTask(eater); 34 // 启动一个生产者线程 35 se.execute(cheafTask); 36 // 启动一个消费者线程 37 se.execute(eaterTask); 38 // 启动一个线程监听当前生产者线程的结果 39 se.execute(new Runnable() { 40 @Override 41 public void run() { 42 try { 43 String st = cheafTask.get(); 44 System.out.println(st); 45 } catch (InterruptedException e) { 46 e.printStackTrace(); 47 } catch (ExecutionException e) { 48 e.printStackTrace(); 49 } 50 51 } 52 }); 53 // 启动一个线程监听当前消费者线程的结果 54 se.execute(new Runnable() { 55 @Override 56 public void run() { 57 try { 58 String st = eaterTask.get(); 59 System.out.println(st); 60 } catch (InterruptedException e) { 61 e.printStackTrace(); 62 } catch (ExecutionException e) { 63 e.printStackTrace(); 64 } 65 } 66 }); 67 //有序地关闭前面已经启动的一些线程 68 } 69 se.shutdown(); 70 } 71 } 72 73 74 class Chef implements Callable { 75 private DiningTable t; 76 private Random random = new Random(); 77 78 public Chef(DiningTable table) { 79 this.t = table; 80 } 81 82 public DiningTable getT() { 83 return t; 84 } 85 86 public void setT(DiningTable t) { 87 this.t = t; 88 } 89 90 public Dish produce() { 91 try { 92 // 模拟做菜用的时间,200-400毫秒一道菜 93 // 跟下面一句的效果一致 94 TimeUnit.MILLISECONDS.sleep(200 + random.nextInt(201)); 95 // Thread.sleep(200 + random.nextInt(201)); 96 } catch (InterruptedException e) { 97 e.printStackTrace(); 98 } 99 Dish food = new Dish();100 return food;101 }102 103 @Override104 public String call() throws Exception {105 for (int i = 0; i < 10; i++) {106 Dish food = produce();107 t.putFood(food);108 }109 return Thread.currentThread().getName() + "结束";110 }111 112 }113 114 115 class Eater implements Callable {116 private DiningTable t;117 private Random random = new Random();118 119 public Eater(DiningTable table) {120 this.t = table;121 }122 123 public DiningTable getT() {124 return t;125 }126 127 public void setT(DiningTable t) {128 this.t = t;129 }130 131 132 public void consume(Dish food) {133 try {134 // 模拟吃菜用的时间135 // 跟下面一句的效果一致136 TimeUnit.MILLISECONDS.sleep(400 + random.nextInt(201));137 // Thread.sleep(400 + random.nextInt(201));138 } catch (InterruptedException e) {139 e.printStackTrace();140 }141 }142 143 @Override144 public String call() throws Exception {145 for (int i = 0; i < 10; i++) {146 Dish food = t.getFood();147 consume(food);148 }149 150 return Thread.currentThread().getName() + "结束";151 }152 153 }154 155 156 class Dish {157 Random random = new Random();158 159 private String foodName;160 161 public Dish() {162 super();163 int posi = random.nextInt(name.length);164 this.foodName = name[posi];165 }166 167 String name[] = { "巫山烤鱼", "清炒小白菜 ", "糖醋里脊", "手撕包菜", "拔丝香蕉", "水煮肉片", "酸菜鱼",168 "土豆肉片" };169 170 public String getName() {171 return foodName;172 }173 174 }175 176 177 class DiningTable {178 // 装食物用的容器179 private LinkedList list = new LinkedList();180 // 定义最大放菜量181 private int maxSize;182 // 创建一把锁183 private Lock lock = new ReentrantLock();184 // 获得当前lock对象的 Condition 实例185 private Condition condition;186 187 public Lock getLock() {188 return lock;189 }190 191 public void setLock(Lock lock) {192 this.lock = lock;193 }194 195 public Condition getCondition() {196 return condition;197 }198 199 public void setCondition(Condition condition) {200 this.condition = condition;201 }202 203 public LinkedList getList() {204 return list;205 }206 207 public void setList(LinkedList list) {208 this.list = list;209 }210 211 public int getMaxSize() {212 return maxSize;213 }214 215 216 public void setMaxSize(int maxSize) {217 this.maxSize = maxSize;218 }219 220 public DiningTable(int maxSize) {221 super();222 this.maxSize = maxSize;223 this.condition = lock.newCondition();224 }225 226 227 public void putFood(Dish food) {228 // 先进行锁定, 与synchronize起的作用类似229 lock.lock();230 try {231 // 防止假唤醒232 while (list.size() >= maxSize) {233 234 System.out.println( "菜已经上满了" + Thread.currentThread().getName() + ",让他们先吃,等消灭几盘再做菜");235 // 如果桌子的菜已经放满了,则让当前线程等待236 this.condition.await();237 }238 list.addLast(food);239 System.out.println(Thread.currentThread().getName() + "烹饪了"240 + food.getName());241 // 通知所有休眠的食客线程继续吃菜242 this.condition.signalAll();243 } catch (Exception e) {244 e.printStackTrace();245 } finally {246 // 解除锁定247 lock.unlock();248 }249 }250 251 252 public Dish getFood() {253 // 先进行锁定, 与synchronize起的作用类似254 lock.lock();255 Dish dish = null;256 try {257 // 防止假唤醒258 while (list.size() <= 0) {259 System.out.println( "菜已经被吃光了" + Thread.currentThread().getName() + "歇会再吃");260 261 // 如果桌子上已经没有菜了,则让当前线程等待262 this.condition.await();263 }264 dish = list.removeFirst();265 System.out.println(Thread.currentThread().getName() + "吃掉了"266 + dish.getName());267 // 通知所有休眠的做菜线程继续做菜268 this.condition.signalAll();269 } catch (Exception e) {270 e.printStackTrace();271 } finally {272 // 解除锁定273 lock.unlock();274 }275 276 return dish;277 }278 279 }
基于java callable及future接口解决生产者消费者问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。