P737 仿真银行出纳员
1 public class Customer { 2 private final int id = count++;//加了ID 3 private static int count = 0;//加了COUNT 4 private final int serviceTime; 5 public Customer(int tm){ 6 serviceTime = tm; 7 } 8 public int getServiceTime(){ 9 return serviceTime; 10 } 11 public String toString(){ 12 return "[customer" + id + "]";//加了CUSTOMER 13 } 14 }
1 import java.util.concurrent.ArrayBlockingQueue; 2 3 public class CustomerLine extends ArrayBlockingQueue<Customer>{ 4 public CustomerLine(int maxSize){ 5 super(maxSize); 6 } 7 public String toString(){ 8 if(this.size() == 0) return "[Empty]"; 9 StringBuilder result = new StringBuilder(); 10 for(Customer customer: this) result.append(customer); 11 return result.toString(); 12 } 13 }
1 import java.util.Random; 2 import java.util.concurrent.TimeUnit; 3 4 public class CustomerGenerator implements Runnable { 5 private CustomerLine customers; 6 private static Random rand = new Random(47); 7 public CustomerGenerator(CustomerLine customers){ 8 this.customers = customers; 9 } 10 public void run(){ 11 try{ 12 while(!Thread.interrupted()){ 13 TimeUnit.MILLISECONDS.sleep(rand.nextInt(300)); 14 customers.put(new Customer(rand.nextInt(1000))); 15 } 16 }catch(InterruptedException e){ 17 System.out.println("CustomerGenerator interrupted"); 18 } 19 System.out.println("CustomerGenerator terminating"); 20 } 21 }
1 import java.util.concurrent.TimeUnit; 2 3 public class Teller implements Runnable ,Comparable<Teller>{ 4 private static int count = 0; 5 private final int id = count++; 6 private boolean servingCustomerLine = true; 7 private int customersServed = 0; 8 private CustomerLine customers; 9 10 public Teller(CustomerLine customers) { 11 this.customers = customers; 12 } 13 14 public String toString() { 15 return "Teller " + id + " "; 16 } 17 18 public String shortString() { 19 return "T " + id; 20 } 21 22 public void run() { 23 try { 24 while (!Thread.interrupted()) { 25 Customer customer = customers.take(); 26 System.out.println(this + " is serving " + customer); 27 TimeUnit.MILLISECONDS.sleep(customer.getServiceTime()); 28 synchronized (this) { 29 customersServed++; 30 while (!servingCustomerLine) wait(); 31 } 32 } 33 } catch (InterruptedException e) { 34 System.out.println(this + " is interrupted."); 35 } 36 System.out.println(this + " terminated"); 37 } 38 39 public synchronized void doSomethingElse(){ 40 System.out.println(this + " is doing something else"); 41 servingCustomerLine = false; 42 customersServed = 0; 43 } 44 45 public synchronized void setCustomersServed(){ 46 assert !servingCustomerLine:"already serving: " + this; 47 servingCustomerLine = true; 48 notifyAll(); 49 } 50 public synchronized int compareTo(Teller other){//排序方法 51 return customersServed < other.customersServed ? -1 : ( 52 customersServed == other.customersServed ? 0 : 1 53 ); 54 } 55 }
1 import java.util.LinkedList; 2 import java.util.PriorityQueue; 3 import java.util.Queue; 4 import java.util.Random; 5 import java.util.concurrent.ExecutorService; 6 import java.util.concurrent.TimeUnit; 7 8 public class TellerManager implements Runnable { 9 private ExecutorService exec; 10 private CustomerLine customers; 11 private PriorityQueue<Teller> workingTellers = new PriorityQueue<Teller>(); 12 private Queue<Teller> tellersDoingOtherThings = new LinkedList<Teller>(); 13 private int adjustmentPeriod; 14 private static Random rand = new Random(47); 15 16 public TellerManager(ExecutorService e, CustomerLine customers, int adjustmentPeriod) { 17 exec = e; 18 this.customers = customers; 19 this.adjustmentPeriod = adjustmentPeriod; 20 Teller teller = new Teller(customers); 21 exec.execute(teller); 22 workingTellers.add(teller); 23 } 24 25 public void adjustTellerNumber() { 26 if (customers.size() / workingTellers.size() > 2) { 27 if (tellersDoingOtherThings.size() > 0) { 28 Teller teller = tellersDoingOtherThings.remove(); 29 teller.setCustomersServed(); 30 workingTellers.offer(teller); 31 return; 32 } 33 Teller teller = new Teller(customers); 34 exec.execute(teller); 35 workingTellers.offer(teller); 36 } else if (workingTellers.size() > 1 && customers.size() / workingTellers.size() < 2) { 37 reassignOneTeller(); 38 } 39 if (customers.size() == 0) { 40 while (workingTellers.size() > 1) 41 reassignOneTeller(); 42 } 43 } 44 45 public void reassignOneTeller() { 46 Teller teller = workingTellers.poll(); 47 teller.doSomethingElse(); 48 tellersDoingOtherThings.add(teller); 49 } 50 51 public void run() { 52 try { 53 while (!Thread.interrupted()) { 54 TimeUnit.MILLISECONDS.sleep(adjustmentPeriod); 55 adjustTellerNumber(); 56 System.out.print(customers + "{"); 57 for (Teller teller : workingTellers) { 58 System.out.print(teller.shortString() + " "); 59 } 60 System.out.println("}"); 61 } 62 } catch (InterruptedException e) { 63 System.out.println(this + "interrupted"); 64 } 65 System.out.println(this + "terminating"); 66 } 67 68 public String toString() { 69 return "TellerManager"; 70 } 71 }
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 import java.util.concurrent.TimeUnit; 4 5 public class BankerTellerSimulation { 6 static final int MAX_LINE_SIZE = 50; 7 static final int ADJUSTMENT_PERIOD = 1000; 8 9 public static void main(String[] args) throws Exception { 10 ExecutorService exec = Executors.newCachedThreadPool(); 11 CustomerLine customers = new CustomerLine(MAX_LINE_SIZE); 12 exec.execute(new CustomerGenerator(customers)); 13 exec.execute(new TellerManager(exec,customers,ADJUSTMENT_PERIOD)); 14 if(args.length > 0) TimeUnit.SECONDS.sleep(new Integer(args[0])); 15 else{ 16 System.out.println("Press 'Enter' to quit" ); 17 System.in.read(); 18 } 19 exec.shutdownNow(); 20 } 21 }