package bank;
public class Customer {
private final int serviceTime;
public Customer(int tm){
serviceTime=tm;
}
public int getServiceTime(){
return serviceTime;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "["+serviceTime+"] ";
}
}
package bank;
import java.util.concurrent.ArrayBlockingQueue;
public class CustomerLine extends ArrayBlockingQueue<Customer>{
public CustomerLine(int capacity) {
super(capacity);
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
// TODO Auto-generated method stub
if(this.size()==0)
return "[empty]";
StringBuilder builder = new StringBuilder();
for(Customer c : this)
builder.append(c);
return builder.toString();
}
}
package bank;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class CustomerGenerator implements Runnable{
private CustomerLine customers;
private static Random rand=new Random(47);
public CustomerGenerator(CustomerLine customers) {
this.customers = customers;
}
@Override
public void run() {
// TODO Auto-generated method stub
try{
while(!Thread.interrupted()){
TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
customers.offer(new Customer(rand.nextInt(1000)));
}
}catch (Exception e) {
// TODO: handle exception
throw new RuntimeException("Customer Generator interrupt!");
}
System.out.println("Customer Generator end!");
}
}
package bank;
import java.util.concurrent.TimeUnit;
public class Teller implements Runnable,Comparable<Teller>{
private static int counter=0;
private int id=counter++;
private CustomerLine customers;
private int serviceNumber;
private boolean serviceCustomer;
public Teller(CustomerLine line){
customers=line;
serviceCustomer=true;
}
public synchronized void doSomethingElse(){
serviceNumber=0;
serviceCustomer=false;
}
public synchronized void serviceCustomers(){
serviceCustomer=true;
notifyAll();
}
@Override
public void run() {
// TODO Auto-generated method stub
try{
while(!Thread.interrupted()){
Customer customer = customers.take();
TimeUnit.MILLISECONDS.sleep(customer.getServiceTime());
synchronized (this) {
serviceNumber++;
while(!serviceCustomer)
wait();
}
}
}catch(InterruptedException e){
throw new RuntimeException("Teller interrupt");
}
System.out.println("Teller service end!");
}
@Override
public int compareTo(Teller t) {
// TODO Auto-generated method stub
if(serviceNumber<t.serviceNumber) return -1;
else if(serviceNumber==t.serviceNumber) return 0;
else return 1;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "Teller "+id+" ";
}
}
package bank;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
public class TellerManager implements Runnable{
private ExecutorService exec;
private CustomerLine customers;
private PriorityQueue<Teller> workingTellers=new PriorityQueue<Teller>();
private Queue<Teller> tellerDoOtherThings=new LinkedList<Teller>();
private int adjustTime;
private static Random rand=new Random(47);
public TellerManager(ExecutorService e,CustomerLine line,int tm){
exec=e;
customers=line;
adjustTime=tm;
Teller teller = new Teller(customers);
exec.execute(teller);
workingTellers.offer(teller);
}
@Override
public void run() {
// TODO Auto-generated method stub
try{
while(!Thread.interrupted()){
TimeUnit.MILLISECONDS.sleep(adjustTime);
adjustTellerNumber();
System.out.print(customers + "{");
for(Teller teller : workingTellers)
System.out.print(teller);
System.out.println("}");
}
}catch(InterruptedException e){
throw new RuntimeException("Teller Manager Innterrupt!");
}
System.out.println("Teller Manager end!");
}
private void adjustTellerNumber() {
// TODO Auto-generated method stub
if(customers.size()/workingTellers.size()>2){
if(tellerDoOtherThings.size()>0){
Teller teller = tellerDoOtherThings.remove();
teller.serviceCustomers();
workingTellers.offer(teller);
return ;
}
Teller teller = new Teller(customers);
workingTellers.offer(teller);
exec.execute(teller);
return ;
}
if(customers.size()/workingTellers.size()<2&&customers.size()/workingTellers.size()>1){
reassignOneTeller();
}
if(customers.size()==0){
while(workingTellers.size()>1)
reassignOneTeller();
}
}
private void reassignOneTeller() {
// TODO Auto-generated method stub
Teller teller = workingTellers.poll();
teller.doSomethingElse();
tellerDoOtherThings.offer(teller);
}
}
package bank;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BankTellerSimulation {
private static int MAX_SIZE=50;
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService exec = Executors.newCachedThreadPool();
CustomerLine customerLine = new CustomerLine(MAX_SIZE);
exec.execute(new CustomerGenerator(customerLine));
exec.execute(new TellerManager(exec, customerLine, 1000));
System.out.println("plase enter to end!");
try {
System.in.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
exec.shutdownNow();
}
}