并发编程实战1
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 }
时间: 2024-10-29 10:46:40