多线程学习(十五)

仿真

多线程的优点之一就是仿真:
银行仿真:

package bank;

public class Customer {
	private final int serverTime;

	public Customer(int serverTime) {
		this.serverTime = serverTime;
	}

	@Override
	public String toString() {
		return " [serverTime=" + serverTime + "] ";
	}

	public int getServerTime() {
		return serverTime;
	}

}
package bank;

import java.util.concurrent.ArrayBlockingQueue;

public class CustomerLine extends ArrayBlockingQueue<Customer> {

	public CustomerLine(int size) {
		super(size);
	}

	@Override
	public String toString() {
		if (this.size() == 0) { // 这里获取 size 是线程安全的
			return "CustomerLine []";
		}
		StringBuilder sb = new StringBuilder();
		for (Customer c : this) { // 这里的遍历也是线程安全的
			sb.append(c);
		}
		return sb.toString();
	}

}

package bank;

import java.util.Random;
import java.util.concurrent.TimeUnit;

public class CustomerGenerator implements Runnable {
	private CustomerLine cl;
	private Random random = new Random();

	public CustomerGenerator(CustomerLine cl) {
		super();
		this.cl = cl;
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				TimeUnit.MILLISECONDS.sleep(random.nextInt(200));
				cl.put(new Customer(random.nextInt(1000)));
			}
		} catch (InterruptedException ie) {
			System.out.println("Generator intrrupt");
		}
	}

}
package bank;

import java.util.concurrent.TimeUnit;

public class Teller implements Runnable, Comparable<Teller> {

	private int servicedNums;
	private CustomerLine line;
	private static int count = 0;
	private final int id = ++count;
	private boolean service = true;

	public Teller(CustomerLine line) {
		super();
		this.line = line;
	}

	@Override
	public int compareTo(Teller otherTeller) {
		return otherTeller.servicedNums < this.servicedNums ? -1
				: (otherTeller.servicedNums > this.servicedNums ? 1 : 0);
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				Customer c = line.take();
				TimeUnit.MILLISECONDS.sleep(c.getServerTime());
				synchronized (this) {
					servicedNums++;
					if (!service) {
						wait();
					}
				}
			}
		} catch (InterruptedException ie) {
			System.out.println(this + " interrupt");
		}
	}

	@Override
	public String toString() {
		return "Teller [id=" + id + "]";
	}

	public synchronized void doSomeThingElse() {
		service = false;
	}

	public synchronized void serviceTheLine() {
		service = true;
		notifyAll();
	}
}

package bank;

import java.util.LinkedList;
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 PriorityQueue<Teller> workingQueue = new PriorityQueue<>();
	private Queue<Teller> doSomeElseQueue = new LinkedList<>();
	private int period;
	private Random random = new Random();
	private CustomerLine line;
	private ExecutorService exec;

	public TellerManager(int period, CustomerLine line, ExecutorService exec) {
		super();
		this.period = period;
		this.line = line;
		this.exec = exec;
		Teller teller = new Teller(line);
		workingQueue.add(teller);
		exec.execute(teller);
	}

	public void ajustTellerNum() {
		if (line.size() / workingQueue.size() > 2) {
			if (doSomeElseQueue.size() > 0) {
				Teller teller = doSomeElseQueue.remove();
				teller.serviceTheLine();
				workingQueue.add(teller);
				return;// 不用向下执行了
			}
			Teller teller = new Teller(line);
			exec.execute(teller);
			workingQueue.add(teller);
			return;
		}
		if (workingQueue.size() > 1 && line.size() / workingQueue.size() < 2) {
			removeOneTeller();
		}
		if (line.size() == 0) {
			while (workingQueue.size() > 0) {
				removeOneTeller();
			}
		}

	}

	private void removeOneTeller() {
		Teller teller = workingQueue.poll();
		teller.doSomeThingElse();
		doSomeElseQueue.offer(teller);
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				TimeUnit.MILLISECONDS.sleep(period);
				ajustTellerNum();
				System.out.println("{ line: " + line);
				StringBuilder sb = new StringBuilder();
				for (Teller t : workingQueue) {
					sb.append(t);
				}
				System.out.println("teller: " + sb.toString()+"}");
			}
		} catch (InterruptedException ie) {
			System.out.println("tellermanager intrrupt");
		}
	}

}
package bank;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class BankTest {
	public static void main(String[] args) throws InterruptedException {
		CustomerLine line=new CustomerLine(30);
		ExecutorService exec=Executors.newCachedThreadPool();
		exec.execute(new CustomerGenerator(line));
		exec.execute(new Teller(line));
		exec.execute(new TellerManager(600, line, exec));
		TimeUnit.MILLISECONDS.sleep(6000);
		exec.shutdownNow();
	}
}

输出结果:
{ line:  [serverTime=899]  [serverTime=705]  [serverTime=227]  [serverTime=950] 
teller: Teller [id=2]Teller [id=3]}
{ line:  [serverTime=227]  [serverTime=950]  [serverTime=491]  [serverTime=320]  [serverTime=881]  [serverTime=229]  [serverTime=737]  [serverTime=153] 
teller: Teller [id=2]Teller [id=3]Teller [id=4]}
{ line:  [serverTime=737]  [serverTime=153]  [serverTime=593]  [serverTime=54]  [serverTime=792]  [serverTime=860]  [serverTime=228]  [serverTime=702] 
teller: Teller [id=2]Teller [id=3]Teller [id=4]}
{ line:  [serverTime=228]  [serverTime=702]  [serverTime=168]  [serverTime=251]  [serverTime=62]  [serverTime=206]  [serverTime=38]  [serverTime=715] 
teller: Teller [id=2]Teller [id=3]Teller [id=4]}
{ line:  [serverTime=62]  [serverTime=206]  [serverTime=38]  [serverTime=715]  [serverTime=307]  [serverTime=173]  [serverTime=758]  [serverTime=857]  [serverTime=570]  [serverTime=657]  [serverTime=467]  [serverTime=382]  [serverTime=35] 
teller: Teller [id=2]Teller [id=3]Teller [id=4]Teller [id=5]}
{ line:  [serverTime=467]  [serverTime=382]  [serverTime=35]  [serverTime=333]  [serverTime=355]  [serverTime=996]  [serverTime=738] 
teller: Teller [id=3]Teller [id=5]Teller [id=4]}
{ line:  [serverTime=355]  [serverTime=996]  [serverTime=738]  [serverTime=130]  [serverTime=149]  [serverTime=448]  [serverTime=595]  [serverTime=504] 
teller: Teller [id=3]Teller [id=5]Teller [id=4]}
{ line:  [serverTime=504]  [serverTime=876]  [serverTime=416]  [serverTime=837]  [serverTime=563]  [serverTime=747]  [serverTime=372] 
teller: Teller [id=3]Teller [id=5]Teller [id=4]}
{ line:  [serverTime=563]  [serverTime=747]  [serverTime=372]  [serverTime=2]  [serverTime=160]  [serverTime=880]  [serverTime=271]  [serverTime=571]  [serverTime=47] 
teller: Teller [id=3]Teller [id=5]Teller [id=4]Teller [id=2]}
Generator intrrupt
Teller [id=2] interrupt
Teller [id=1] interrupt
Teller [id=3] interrupt
tellermanager intrrupt
Teller [id=5] interrupt
Teller [id=4] interrupt

posted @ 2017-05-15 21:22  风中小蘑菇  阅读(126)  评论(0编辑  收藏  举报