BankTellerSimulation

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();
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章