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 }