美文网首页
多线程模拟银行出纳和管理过程

多线程模拟银行出纳和管理过程

作者: 西5d | 来源:发表于2017-12-20 22:31 被阅读14次

    这个例子来自java编程思想,模拟了银行出纳的多线程场景

    package com.igoso.learning;
    
    import java.util.LinkedList;
    import java.util.PriorityQueue;
    import java.util.Queue;
    import java.util.Random;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    /**
     * created by igoso at 2017/12/20
     * 模仿银行出纳的多线程服务场景,java编程思想
     **/
    public class BankTellerSimulation {
        static final int MAX_LINE_SIZE = 50;
        static final int ADJUSTMENT_PERIOD = 1000;
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService exec = Executors.newCachedThreadPool();
            //if customer line is too line , customer will leave
            CustomerLine customers = new CustomerLine(MAX_LINE_SIZE);
            exec.execute(new CustomerGenerator(customers));
            //manager add and remove tellers as necessary
            exec.execute(new TellerManager(exec,customers,ADJUSTMENT_PERIOD));
    
    //        exec.shutdownNow();
        }
    
    }
    
    
    class Customer{
        private final int serviceTime;
        public Customer(int tm){
            serviceTime = tm;
        }
    
        public int getServiceTime() {
            return serviceTime;
        }
    
        @Override
        public String toString() {
            return "[" + serviceTime + "]";
        }
    }
    
    class CustomerLine extends ArrayBlockingQueue<Customer>{
        public CustomerLine(int capacity) {
            super(capacity);
        }
    
        @Override
        public String toString() {
            if(this.size()==0){
                return "[empty]";
            }
            StringBuilder sb = new StringBuilder();
            for(Customer customer: this){
                sb.append(customer);
            }
            return sb.toString();
        }
    
    }
    
    class CustomerGenerator implements Runnable{
        private CustomerLine customers;
        private static Random random = new Random(47);
        public CustomerGenerator(CustomerLine customerLine) {
            this.customers = customerLine;
        }
    
        public void run() {
            try {
                while (!Thread.interrupted()){
                    TimeUnit.MILLISECONDS.sleep(random.nextInt(300));
                    customers.put(new Customer(random.nextInt(8000)));
                }
            }catch (InterruptedException e){
                System.out.println("Customer generator interrupted");
            }
            System.out.println("Customer generator terminating");
        }
    }
    
    class Teller implements Runnable , Comparable<Teller>{
        private static int counter = 0;
        private final int id = counter++;
        private int customerServed = 0;
        private CustomerLine customers;
        private boolean servingCustomerLine = true;
    
        public Teller(CustomerLine customers){
            this.customers = customers;
        }
    
        public synchronized int compareTo(Teller o) {
            return customerServed < o.customerServed?-1:(customerServed == o.customerServed?0:1);
        }
    
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    Customer customer = customers.take();
                    TimeUnit.MILLISECONDS.sleep(customer.getServiceTime());
                    synchronized (this) {
                        customerServed++;
                        while (!servingCustomerLine) {
                            wait();
                        }
                    }
                }
            } catch (InterruptedException e) {
                System.out.println(this + "interrupted");
            }
            System.out.println(this + "terminating");
        }
    
        public synchronized void doSomethingElse() {
            customerServed=0;
            servingCustomerLine=false;
        }
    
        public synchronized void serveCustomerLine(){
            assert !servingCustomerLine:"already serving:"+ this;
            servingCustomerLine=true;
            notifyAll();
        }
    
        @Override
        public String toString() {
            return "Teller " + id + " ";
        }
    
        public String shortString() {
            return "T" + id;
        }
    
    }
    
    class TellerManager implements Runnable{
        private ExecutorService exec;
        private CustomerLine customers;
        private PriorityQueue<Teller> workingTellers= new PriorityQueue<Teller>();
        private Queue<Teller> tellerDoingOtherThings = new LinkedList<Teller>();
        private int adjustmentPeriod;
        private static Random random = new Random(47);
        public TellerManager(ExecutorService exec, CustomerLine customers, int adjustmentPeriod){
            this.exec = exec;
            this.customers = customers;
            this.adjustmentPeriod = adjustmentPeriod;
    
            //start with a new single teller
            Teller teller = new Teller(customers);
            exec.execute(teller);
            workingTellers.add(teller);
        }
    
        //空闲分配任务
        public void adjustTellerNumber(){
            if(customers.size()/ workingTellers.size()>2){
                //if tellers are on break or doing
                // another job, bring one back
                if(tellerDoingOtherThings.size()>0){
                    Teller teller = tellerDoingOtherThings.remove();
                    teller.serveCustomerLine();
                    workingTellers.offer(teller);
                    return;
                }
                //hire a new teller
                Teller teller = new Teller(customers);
                exec.execute(teller);
                workingTellers.add(teller);
                return;
            }
    
            //if line is short enough, remove a teller
            if(workingTellers.size()>1 && customers.size()/workingTellers.size()<2){
                reassignOneTeller();
            }
    
            if(customers.size() == 0){
                while (workingTellers.size()>1){
                    reassignOneTeller();
                }
            }
    
        }
    
        private void reassignOneTeller(){
            Teller teller = workingTellers.poll();
            teller.doSomethingElse();
            tellerDoingOtherThings.offer(teller);
        }
    
    
        public void run() {
            try {
                while (!Thread.interrupted()){
                    TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
                    adjustTellerNumber();
                    System.out.print(customers + "{");
                    for(Teller teller : workingTellers){
                        System.out.print(teller.shortString() + " ");
                    }
                    System.out.println("}");
                }
            }catch (InterruptedException e){
                System.out.println(this + " interrupted");
            }
            System.out.println(this + "terminating");
        }
    }
    

    相关文章

      网友评论

          本文标题:多线程模拟银行出纳和管理过程

          本文链接:https://www.haomeiwen.com/subject/okpnwxtx.html