• Java多线程之银行出纳员仿真


    package concurrent;
    
    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;
    
    class Customer {
        private final int serviceTime;
    
        public Customer(int tm) {
            serviceTime = tm;
        }
    
        public int getServiceTime() {
            return serviceTime;
        }
    
        public String toString() {
            return "[" + serviceTime + "]";
        }
    }
    
    class CustomerLine extends ArrayBlockingQueue<Customer> {
        public CustomerLine(int maxLineSize) {
            super(maxLineSize);
        }
    
        public String toString() {
            if (this.size() == 0)
                return "[Empty]";
            
            StringBuilder result = new StringBuilder();
            for (Customer customer : this) {
                result.append(customer);
            }
            return result.toString();
        }
    }
    
    class CustomerGenerator implements Runnable {
        private CustomerLine customers;
        private static Random rand = new Random(47);
    
        public CustomerGenerator(CustomerLine cq) {
            customers = cq;
        }
    
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
                    customers.put(new Customer(rand.nextInt(1000)));
    //                System.out.println(customers.toString());
                }
            } catch (InterruptedException e) {
                System.out.println("CustomerGenerator interrupted");
            }
            System.out.println("CustomerGenerator terminating");
        }
    }
    
    class Teller implements Runnable, Comparable<Teller> {
        private static int counter = 0;
        private final int id = counter++;
        private int customersServed = 0;// 已经服务的客户
        private CustomerLine customers;// 客户队列
        private boolean servingCustomerLine = true;// 是否正在服务客户
    
        public Teller(CustomerLine cq) {
            customers = cq;
        }
    
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    Customer customer = customers.take();
                    TimeUnit.MILLISECONDS.sleep(customer.getServiceTime());
                    synchronized (this) {
                        customersServed++;
                        while (!servingCustomerLine)
                            wait();
                    }
                }
            } catch (InterruptedException e) {
                System.out.println(this + " interrupted");
            }
            System.out.println(this + " terminating");// 结束
        }
    
        public synchronized void doSomethingElse() {
            customersServed = 0;
            servingCustomerLine = false;
        }
    
        public synchronized void serveCustomerLine() {
            assert !servingCustomerLine : "already serving:" + this;
            servingCustomerLine = true;
            notifyAll();
        }
    
        public String toString() {
            return "Teller " + id + " ";
        }
    
        public String shortString() {
            return "T" + id;
        }
    
        public synchronized int compareTo(Teller other) {
            return customersServed < other.customersServed ? -1
                    : (customersServed == other.customersServed ? 0 : 1);
        }
    }
    
    class TellerManager implements Runnable {
        private ExecutorService exec;
        private CustomerLine customers;
        private PriorityQueue<Teller> workingTellers = new PriorityQueue<Teller>();
        private Queue<Teller> tellersDoingOtherThings = new LinkedList<Teller>();
        private int adjustmentPeriod;
        private static Random rand = new Random(47);
    
        public TellerManager(ExecutorService e, CustomerLine customers,
                int adjustmentPeriod) {
            exec = e;
            this.customers = customers;
            this.adjustmentPeriod = adjustmentPeriod;
            Teller teller = new Teller(customers);
            exec.execute(teller);
            workingTellers.add(teller);
        }
    
        /**
         * 调整出纳员数量
         * */
        public void adjustTellerNumber() {
            if (customers.size() / workingTellers.size() > 2) {
                if (tellersDoingOtherThings.size() > 0) {
                    Teller teller = tellersDoingOtherThings.remove();
                    teller.serveCustomerLine();
                    workingTellers.offer(teller);
                    return;
                }
                Teller teller = new Teller(customers);
                exec.execute(teller);
                workingTellers.add(teller);
                return;
            }
            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();
            tellersDoingOtherThings.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");
        }
    
        public String toString() {
            return "TellerManager";
        }
    }
    
    public class BankTellerSimulation {
        static final int MAX_LINE_SIZE = 50;
        static final int ADJUSTMENT_PERIOD = 1000;
    
        public static void main(String[] args) throws Exception {
            ExecutorService exec = Executors.newCachedThreadPool();
            CustomerLine customers = new CustomerLine(MAX_LINE_SIZE);
            exec.execute(new CustomerGenerator(customers));
            exec.execute(new TellerManager(exec, customers, ADJUSTMENT_PERIOD));
            if (args.length > 0)
                TimeUnit.SECONDS.sleep(new Integer(args[0]));
            else {
                System.out.println("Press 'Enter' to quit");
                System.in.read();
            }
            exec.shutdownNow();
        }
    }
  • 相关阅读:
    在 Cocos2d-x 中添加自己的微博链接
    关于屏幕适配
    [抽象工厂模式]在游戏开发中的应用
    字符串排列组合
    子矩阵最大和
    网易游戏编程题第二题
    动态规划,最大子段和
    C++的四种显示类型转换
    多线程编程
    预处理等等
  • 原文地址:https://www.cnblogs.com/zhuawang/p/3788227.html
Copyright © 2020-2023  润新知