并发---仿真(银行出纳员仿真 )

仿真

  • 通过使用并发,仿真的每个构件都可以成为其自身的任务,这使得仿真更容易编程。

银行出纳员仿真

  • 可以表示任何属于以下的情况:对象随机地出现,并且要求由数量有限的服务器提供随机数量的服务时间。通过构建仿真可以确定理想的服务器数量。
package com21仿真;

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 Panda on 2018/5/30.
 */
class Customer{
    private final int serviceTime;    //服务时间
    public Customer(int serviceTime){this.serviceTime=serviceTime;}
    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 random = new Random(47);
    public CustomerGenerator(CustomerLine customers) {this.customers = customers;}
    @Override
    public void run() {
        try{
            while (!Thread.interrupted()){
                TimeUnit.MILLISECONDS.sleep(random.nextInt(300));
                customers.put(new Customer(random.nextInt(1000))); //服务时间 放入排队队列
            }
        }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 customersLine;  //队列
    private boolean servingCustomerLine=true;

    public Teller(CustomerLine customers) {
        this.customersLine = customers;
    }
    @Override
    public synchronized int compareTo(Teller o) {
        return customersServed< o.customersServed?-1:(customersServed==o.customersServed?0:1);
    }

    @Override
    public void run() {
      try{
          while (!Thread.interrupted()){
              //检索并移除此队列的头部,如果此队列不存在任何元素,则一直等待
              Customer customer = customersLine.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;}
}
   class TellerManager implements Runnable{
       private ExecutorService executorService;
       private CustomerLine customersLine;
       private PriorityQueue<Teller> workingTells=new PriorityQueue<>();  //优先级
       private Queue<Teller> tellersDoingOtherThing=new LinkedList<>();
       private int adjustmentPeriod;
       private static Random random = new Random(47);
       public TellerManager(ExecutorService executorService ,CustomerLine customersLine,int adjustmentPeriod){
           this.executorService=executorService;
           this.customersLine=customersLine;
           this.adjustmentPeriod=adjustmentPeriod;

           Teller teller = new Teller(customersLine);
           executorService.execute(teller);
           workingTells.add(teller);
       }


       public void adjustTellerNumber(){
           //排队比较多 增加teller
        //   System.out.println("customersLine.size()"+customersLine.size());
        //   System.out.println("workingTells.size()"+workingTells.size());
           if(customersLine.size()/workingTells.size()>2){
               if(tellersDoingOtherThing.size()>0){
                   Teller teller=tellersDoingOtherThing.remove();
                   teller.serveCustomerLine();
                   //向优先级队列中插入指定的元素。
                   workingTells.offer(teller);
                   return;
               }
               //新增加teller
               Teller teller = new Teller(customersLine);
               executorService.execute(teller);
               workingTells.add(teller);
               return;
           }
           //如果排队的比较少,减少teller
           if(workingTells.size()>1&&customersLine.size()/workingTells.size()<2){
               reassignOneTeller();
           }
           //如果没有排队,只需要一个teller
           if(customersLine.size()==0){
               while (workingTells.size()>1)  reassignOneTeller();
           }
       }

       private void reassignOneTeller(){
           Teller teller=workingTells.poll();
           teller.doSomethingElse();
           tellersDoingOtherThing.offer(teller);
       }


       @Override
       public void run() {
          try{
              while (!Thread.interrupted()){
                  TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
                  adjustTellerNumber();
                  System.out.print(customersLine+"{ ");
                  for(Teller teller:workingTells){
                      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 "TellerManger ";}
   }

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 executorService = Executors.newCachedThreadPool();
        CustomerLine customersLine =new CustomerLine(MAX_LINE_SIZE);
        executorService.execute(new CustomerGenerator(customersLine));
        executorService.execute(new TellerManager(executorService,customersLine,ADJUSTMENT_PERIOD));

        if(args.length>0) TimeUnit.SECONDS.sleep(new Integer(args[0]));
        else {
            System.out.printf("Press Enter to quit") ;
            System.in.read();
        }
        executorService.shutdownNow();
    }
    /**
     * 
     * customersLine.size()3
     workingTells.size()1
     [200][207]{ T1 T0 }
     customersLine.size()4
     workingTells.size()2
     [861][258][140][322]{ T1 T0 }
     customersLine.size()6
     workingTells.size()2
     [575][342][804][826][896][984]{ T2 T0 T1 }
     customersLine.size()10
     workingTells.size()3
     [984][810][141][12][689][992][976][368][395][354]{ T3 T2 T1 T0 }
     customersLine.size()8
     workingTells.size()4
     [395][354][222][687][634][317][242][698]{ T3 T2 T1 T0 }
     customersLine.size()8
     workingTells.size()4
     [698][899][665][909][209][158][273][894]{ T3 T2 T1 T0 }
     customersLine.size()7
     workingTells.size()4
     [984][533][8][328][779][882][37]{ T2 T0 T1 }
     */
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值