多线程案例

package com.current.demo;

import java.io.IOException;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.*;

/**

  • 程序描述:
  •  随机生成多个客户
    
  •  业务员管理器会根据客户的数量分配不同业务员的数量
    
  •  当客户逐渐变少时,当前工作的业务员也会有一部分被回收掉(并不是真正意义的回收,而是保存在另一个队列里面)
    
  •  然而,当客户又变多时,之前被回收的部分业务员会回来重新工作
    
  • */

//Customer是个只是读的对象 (代表客户)
class Customer{
//要是这个客户服务的时长
private final int serverTime;

public Customer(int m){
    System.out.println("create Customer finish serverTime="+m);
    serverTime = m;
}
//获取时长
public int getServerTime(){
    return serverTime;
}

//打印时长
public String toString(){
    return "[" + serverTime + "]";
}

}

//表示所有等待的客户
class CustomerLine extends ArrayBlockingQueue{

//最大等待客户的数量
public CustomerLine(int maxLineSize){
    super(maxLineSize);
}


//定制打印格式
public String toString(){
    //如果等待客户为0 就打印empty
    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){
    System.out.println("create CustomerGenerator finshed");
    customers = cq;
}

@Override
public void run(){
    System.out.println("create CustomerGenerator is run");

    try{
        //不断的模拟新的客户
        while(!Thread.interrupted()){
            //随机睡眠 模拟新来一个客户 ------
            TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
            customers.put(new Customer(rand.nextInt(1000)));
            //---------
        }
    }catch (InterruptedException e){
        System.out.println("CustomerGenerator interrupted");
    }
    System.out.println("CustomerGenerator terminating");
}

}

//具体处理客户的出纳员
class Teller implements Runnable,Comparable{
//------------ 这两个字段用来表示出纳员的id(标识) -----
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){
    System.out.println("ctreate Teller finshed id="+id);
    customers = cq;
}

//出纳员工作入口
@Override
public void run() {
    try{
        while(!Thread.interrupted()){
            //从等待客户列表拿出等待的客户 并进行处理
            Customer customer = customers.take();
            TimeUnit.MILLISECONDS.sleep(customer.getServerTime());

            //锁定当前对象
            synchronized (this){
                //当前出纳员处理的客户数量+1
                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> workingTellerss = new PriorityQueue<Teller>();

//LinkeList implements Deque Deque implements Queue (才知道)
//当前没有工作的业务员
private Queue<Teller> tellersDoingOtherThings = new LinkedList<>();

//这个代表的是某一个界值吧(睡眠的时间)
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);
    workingTellerss.add(teller);
}

public void adjustTellerNumber(){
    //如果等待队列中的长度 / 业务员的数量 大于2
    if(customers.size() / workingTellerss.size() > 2){
        //如果这个业务员待处理的数量大于0
        if(tellersDoingOtherThings.size() > 0){
            //拿出一个
            Teller teller = tellersDoingOtherThings.remove();
            //标志为已经处理
            teller.serveCustomerLine();
            workingTellerss.add(teller);
            return;
        }
        Teller teller = new Teller(customers);
        exec.execute(teller);
        workingTellerss.add(teller);
        return;
    }

    if(workingTellerss.size() > 1 && customers.size() / workingTellerss.size() < 2){
        reassignOneTeller();
    }
    if(customers.size() == 0){
        while(workingTellerss.size() > 1){
            reassignOneTeller();
        }
    }
}

private void reassignOneTeller(){
    Teller teller = workingTellerss.poll();
    teller.doSomethingElse();
    tellersDoingOtherThings.offer(teller);
}

@Override
public void run() {
    try{
        while (!Thread.interrupted()){
            //睡眠
            TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
            adjustTellerNumber();
            System.out.println(customers + " { ");
            //
            for(Teller teller : workingTellerss){
                System.out.print(teller.shortString() + ",");
            }
            System.out.println();
            System.out.println("}");
        }
    }catch (InterruptedException e){
        System.out.println(this + " interrupted");
    }
    System.out.println(this + " terminating");
}

public String toString(){
    return "TellerManager";
}

}

class BankTellerSimulation {
static final int MAX_LIME_SIZE = 50;
static final int ADJUSTMENT_PERIOD = 1000;

public static void main(String[] args) throws IOException, InterruptedException {

    ExecutorService exec = Executors.newCachedThreadPool();
    CustomerLine customers = new CustomerLine(MAX_LIME_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.shutdown();
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值