并发编程之基础( 五)

并发编程实战1


 

该示例代码模拟银行出纳员服务的过程。银行中随时都会来顾客,而且每位顾客的服务时间长短不确定。当顾客数量多时需要增加出纳,当顾客数量少时需要减少出纳并让出纳去干别的事情。

  关键字

  • Runnable
  • Comparable<T>
  • Thread.interrupted()
  • wait/notifyAll
  • PriorityQueue
  • ExecutorService
  1 package com.dy.xidian;
  2 
  3 import java.util.LinkedList;
  4 import java.util.PriorityQueue;
  5 import java.util.Queue;
  6 import java.util.Random;
  7 import java.util.concurrent.ArrayBlockingQueue;
  8 import java.util.concurrent.ExecutorService;
  9 import java.util.concurrent.Executors;
 10 import java.util.concurrent.TimeUnit;
 11 
 12 class Customer {
 13     private final int serviceTime;
 14     public Customer(int tm) {
 15         serviceTime = tm;
 16     }
 17     public int getService() {
 18         return serviceTime;
 19     }
 20     public String toString() {
 21         return "[" + serviceTime + "]";
 22     }
 23 }
 24 
 25 @SuppressWarnings("serial")
 26 class CustomerLine extends ArrayBlockingQueue<Customer> {
 27 
 28     public CustomerLine(int maxLineSize) {
 29         super(maxLineSize);
 30     }
 31 
 32     public String toString() {
 33         if (this.size() == 0)
 34             return "[Empty]";
 35         StringBuilder result = new StringBuilder();
 36         for (Customer customer : this)
 37             result.append(customer);
 38         return result.toString();
 39     }
 40 
 41 }
 42 
 43 class CustomerGenerator implements Runnable {
 44     private CustomerLine customers;
 45     private static Random rand = new Random(47);
 46 
 47     public CustomerGenerator(CustomerLine cq) {
 48         customers = cq;
 49     }
 50 
 51     @Override
 52     public void run() {
 53         try {
 54             while (!Thread.interrupted()) {
 55                 TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
 56                 customers.put(new Customer(rand.nextInt(1000)));
 57             }
 58         } catch (InterruptedException e) {
 59             System.out.println("CustomerGenerator interrupted!");
 60         }
 61         System.out.println("CustomerGenerator terminating");
 62     }
 63 }
 64 
 65 class Teller implements Runnable {
 66     private static int counter = 0;
 67     private final int id = counter++;
 68     private int customerServed = 0;
 69     private CustomerLine customers;
 70     private boolean servingCustomerLine = true;
 71 
 72     public Teller(CustomerLine customers) {
 73         super();
 74         this.customers = customers;
 75     }
 76 
 77     @Override
 78     public void run() {
 79         try {
 80             while (!Thread.interrupted()) {
 81                 Customer customer = customers.take();
 82                 TimeUnit.MILLISECONDS.sleep(customer.getService());
 83                 synchronized (this) {
 84                     customerServed++;
 85                     while (!servingCustomerLine)
 86                         wait();
 87                 }
 88             }
 89         } catch (InterruptedException e) {
 90             System.out.println(this + "interrupted!");
 91         }
 92         System.out.println(this + "terminating!");
 93     }
 94 
 95     public synchronized void doSomethingElse() {
 96         customerServed = 0;
 97         servingCustomerLine = false;
 98     }
 99 
100     public synchronized void serveCustomerLine() {
101         assert !servingCustomerLine : "already serving" + this;
102         servingCustomerLine = true;
103         notifyAll();
104     }
105 
106     public String toString() {
107         return "Teller " + id + " ";
108     }
109 
110     public String shortString() {
111         return "T" + id;
112     }
113 
114     public synchronized int compateTo(Teller other) {
115         if (customerServed > other.customerServed)
116             return 1;
117         if (customerServed < other.customerServed)
118             return -1;
119         return 0;
120     }
121 }
122 
123 class TellerManger implements Runnable {
124     private ExecutorService exec;
125     private CustomerLine customers;
126     private PriorityQueue<Teller> workingTellers = new PriorityQueue<Teller>();
127     private Queue<Teller> tellersDoingOtherThings = new LinkedList<Teller>();
128     private int adjustmentPeriod;
129 
130     public TellerManger(ExecutorService ex, CustomerLine customers,
131             int adjustmentPeriod) {
132         super();
133         this.exec = ex;
134         this.customers = customers;
135         this.adjustmentPeriod = adjustmentPeriod;
136         Teller teller = new Teller(customers);
137         exec.execute(teller);
138         workingTellers.add(teller);
139     }
140 
141     public void adjustTellerNumber() {
142         if (customers.size() / workingTellers.size() > 2) {
143             Teller teller = tellersDoingOtherThings.remove();
144             teller.serveCustomerLine();
145             workingTellers.offer(teller);
146             return;
147         }
148         if (workingTellers.size() > 1
149                 && customers.size() / workingTellers.size() < 2)
150             reassignOneTeller();
151         if (customers.size() == 0)
152             while (workingTellers.size() > 1)
153                 reassignOneTeller();
154 
155     }
156 
157     private void reassignOneTeller() {
158         Teller teller = workingTellers.poll();
159         teller.doSomethingElse();
160         tellersDoingOtherThings.offer(teller);
161     }
162 
163     @Override
164     public void run() {
165         try {
166             while (!Thread.interrupted()) {
167                 TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
168                 adjustTellerNumber();
169                 System.out.println(customers + " { ");
170                 for (Teller teller : workingTellers) {
171                     System.out.println(teller.shortString() + " ");
172                 }
173                 System.out.println("}");
174             }
175         } catch (InterruptedException e) {
176             System.out.println(this + "interrupted");
177         }
178         System.out.println(this + "terminating");
179     }
180 }
181 
182 public class BankTellerSimulation {
183     static final int MAX_LINE_SIZE = 50;
184     static final int ADJUSTMENT_PERIOD = 1000;
185 
186     public static void main(String[] args) throws Exception {
187         ExecutorService exec = Executors.newCachedThreadPool();
188         CustomerLine customers = new CustomerLine(MAX_LINE_SIZE);
189         exec.execute(new CustomerGenerator(customers));
190         exec.execute(new TellerManger(exec, customers, ADJUSTMENT_PERIOD));
191         if (args.length > 0)
192             TimeUnit.SECONDS.sleep(new Integer(args[0]));
193         else {
194             System.out.println("press 'Enter' to quit");
195             System.in.read();
196         }
197         exec.shutdownNow();
198     }
199 }
View Code

并发编程实战2


  该代码模拟的了汽车组装线,每辆Car通过流水线生产,通过机器人来安装汽车发动机、车厢和轮子。Car是通过CarQueue(阻塞队列)从一个地方传送到另一个地方。ChassisBuilder创建了一个未加修饰的Car,并将它放在一个CarQueue中。Assembler从CarQueue中取走Car,并雇佣Robot对其进行加工。CyclicBarrier使Assembler等待,等到所有的Robot都完成后,将Car放置在即将离开它的CarQueue中,然后被传送至下一个操作。最终的CarQueue的消费者是一个Reporter对象,它只打印Car,显示所有的任务已经正确完成。Robot是在池中管理的,当需要完成工作时,就会从池中雇佣适当的Robot,使用完之后会归还Robot.

  关键字

  • Runnable
  • Thread.interrupted()
  • wait/notifyAll
  • CyclicBarrier
  • 对象池
  • synchronized
  • 泛型
  1 package com.dy.xidian;
  2 
  3 import java.util.HashSet;
  4 import java.util.Set;
  5 import java.util.concurrent.BrokenBarrierException;
  6 import java.util.concurrent.CyclicBarrier;
  7 import java.util.concurrent.ExecutorService;
  8 import java.util.concurrent.Executors;
  9 import java.util.concurrent.LinkedBlockingQueue;
 10 import java.util.concurrent.TimeUnit;
 11 
 12 class Car {
 13     private final int id;
 14     private boolean engine = false, driveTrain = false, wheels = false;
 15 
 16     public Car(int idn) {
 17         id = idn;
 18     }
 19 
 20     public Car() {
 21         id = -1;
 22     }
 23 
 24     public synchronized int gerId() {
 25         return id;
 26     }
 27 
 28     public synchronized void addEngine() {
 29         engine = true;
 30     }
 31 
 32     public synchronized void addDriveTrain() {
 33         driveTrain = true;
 34     }
 35 
 36     public synchronized void addWheels() {
 37         wheels = true;
 38     }
 39 
 40     public synchronized String toString() {
 41         return "Car " + id + " engine " + engine + " driveTrain: " + driveTrain
 42                 + " wheels: " + wheels + " ]";
 43     }
 44 }
 45 
 46 class CarQueue extends LinkedBlockingQueue<Car> {
 47 }
 48 
 49 class ChassisBuilder implements Runnable {
 50     private CarQueue carQueue;
 51     public int counter = 0;
 52     public ChassisBuilder(CarQueue cq) {
 53         carQueue = cq;
 54     }
 55 
 56     @Override
 57     public void run() {
 58         try {
 59             while (!Thread.interrupted()) {
 60                 TimeUnit.MILLISECONDS.sleep(500);
 61                 Car c = new Car(counter++);
 62                 System.out.println("ChassisBuilder created " + c);
 63                 carQueue.put(c);
 64             }
 65         } catch (InterruptedException e) {
 66             System.out.println("Interrupted: ChassisBuilder");
 67         }
 68         System.out.println("ChassisBuilder off");
 69     }
 70 
 71 }
 72 
 73 abstract class Robot implements Runnable {
 74     private RobotPool pool;
 75     public Robot(RobotPool p) {
 76         pool = p;
 77     }
 78     protected Assembler assembler;
 79 
 80     public Robot assignAssembler(Assembler assembler) {
 81         this.assembler = assembler;
 82         return this;
 83     }
 84 
 85     private boolean engage = false;
 86 
 87     public synchronized void engage() {
 88         engage = true;
 89         notifyAll();
 90     }
 91 
 92     abstract protected void performService();
 93 
 94     public void run() {
 95         try {
 96             powerDown();
 97             while (!Thread.interrupted()) {
 98                 performService();
 99                 try {
100                     assembler.barrier().await();
101                 } catch (BrokenBarrierException e) {
102                     throw new RuntimeException(e);
103                 }
104                 powerDown();
105             }
106         } catch (InterruptedException e) {
107             System.out.println("Exiting " + this + " via interrupt");
108         }
109         System.out.println(this + " off");
110     }
111 
112     private synchronized void powerDown() throws InterruptedException {
113         engage = false;
114         assembler = null;
115         pool.release(this);
116         while (engage == false)
117             wait();
118     }
119 
120     public String toString() {
121         return getClass().getName();
122     }
123 }
124 
125 class EngineRobot extends Robot {
126     public EngineRobot(RobotPool pool) {
127         super(pool);
128     }
129     protected void performService() {
130         System.out.println(this + " installing engine");
131         assembler.car().addEngine();
132     }
133 }
134 
135 class DriveTrainRobot extends Robot {
136 
137     public DriveTrainRobot(RobotPool p) {
138         super(p);
139     }
140 
141     @Override
142     protected void performService() {
143         System.out.println(this + " installing DriveTrain");
144         assembler.car().addDriveTrain();
145     }
146 
147 }
148 
149 class WheelRobot extends Robot {
150 
151     public WheelRobot(RobotPool p) {
152         super(p);
153     }
154 
155     @Override
156     protected void performService() {
157         System.out.println(this + " installing wheels");
158         assembler.car().addWheels();
159     }
160 }
161 
162 class RobotPool {
163     private Set<Robot> pool = new HashSet<Robot>();
164 
165     public synchronized void add(Robot r) {
166         pool.add(r);
167         notifyAll();
168     }
169 
170     public synchronized void hire(Class<? extends Robot> robotType, Assembler d)
171             throws InterruptedException {
172         for (Robot r : pool)
173             if (r.getClass().equals(robotType)) {
174                 pool.remove(r);
175                 r.assignAssembler(d);
176                 r.engage();
177                 return;
178             }
179         wait();
180         hire(robotType, d);
181     }
182 
183     public synchronized void release(Robot r) {
184         add(r);
185     }
186 }
187 
188 class Assembler implements Runnable {
189     private CarQueue chassisQueue, finishingQueue;
190     private Car car;
191     private CyclicBarrier barrier = new CyclicBarrier(4);
192     private RobotPool robotPool;
193 
194     public Assembler(CarQueue chassisQueue, CarQueue finishingQueue,
195             RobotPool robotPool) {
196         super();
197         this.chassisQueue = chassisQueue;
198         this.finishingQueue = finishingQueue;
199         this.robotPool = robotPool;
200     }
201 
202     public Car car() {
203         return car;
204     }
205 
206     public CyclicBarrier barrier() {
207         return barrier;
208     }
209 
210     @Override
211     public void run() {
212         try {
213             while (!Thread.interrupted()) {
214                 car = chassisQueue.take();
215                 robotPool.hire(EngineRobot.class, this);
216                 robotPool.hire(DriveTrainRobot.class, this);
217                 robotPool.hire(WheelRobot.class, this);
218                 try {
219                     barrier.await();
220                 } catch (BrokenBarrierException e) {
221                     throw new RuntimeException(e);
222                 }
223                 finishingQueue.put(car);
224             }
225         } catch (InterruptedException e) {
226             System.out.println("Exiting Assembler via interrupt");
227         }
228         System.out.println("Assemble off");
229     }
230 
231 }
232 
233 class Reporter implements Runnable {
234     private CarQueue carQueue;
235     public Reporter(CarQueue cq) {
236         carQueue = cq;
237     }
238 
239     @Override
240     public void run() {
241         try {
242             while (!Thread.interrupted())
243                 System.out.println(carQueue.take());
244         } catch (InterruptedException e) {
245             System.out.println("Exiting Reporter via interrupt");
246         }
247         System.out.println("Reporter off");
248     }
249 }
250 
251 public class CarBuilder {
252     public static void main(String[] args) throws InterruptedException {
253         CarQueue chassisQueue = new CarQueue(), finishingQueue = new CarQueue();
254         ExecutorService exec = Executors.newCachedThreadPool();
255         RobotPool robotPool = new RobotPool();
256         exec.execute(new EngineRobot(robotPool));
257         exec.execute(new DriveTrainRobot(robotPool));
258         exec.execute(new WheelRobot(robotPool));
259         exec.execute(new Assembler(chassisQueue, finishingQueue, robotPool));
260         exec.execute(new Reporter(finishingQueue));
261         exec.execute(new ChassisBuilder(chassisQueue));
262         TimeUnit.SECONDS.sleep(7);
263         exec.shutdownNow();
264     }
265 }
View Code

 

 

posted @ 2016-04-03 19:22  被罚站的树  阅读(203)  评论(0编辑  收藏  举报