基于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  @Override

104  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  @Override

144  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 }

 

你可能感兴趣的:(callable)