聲明:文章內容全都是自己的學習總結,如有不對的地方請大家幫忙指出。有需要溝通交流的可加我QQ羣:425120333
接下來的三篇都是關於學習了多線程之後的應用,參考的都是《java編程思想》這本書裏的關於多線程仿真篇的內容。只是自己理解了後,重新打了一遍,
說真的,學習java光看是沒什麼用的,我一開始看書中的內容的時候,基本沒看懂是什麼意思,我跟着代碼模仿着敲了一遍,在這過程中我也考慮了爲啥要這樣寫。
這樣等你一遍下來後,你就懂了80%左右了,然後你在自己不看再敲一遍,碰到不會的再看下,整個流程弄完了,再在紙上畫下整個基本流程。這時你就懂了99%了,
剩下的1%你再練習一兩遍就差不多了,僅僅只是看看,效果真的不大。
廢話就說到這,接下來看下代碼:
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;
public class BankTellerPractice {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
CustomerLine line = new CustomerLine(50);
service.execute(new GenrCustomer(line));
new TellerManager(service, line);
try {
TimeUnit.SECONDS.sleep(7);
} catch (InterruptedException e) {
e.printStackTrace();
}
service.shutdownNow();
}
}
class Customer {
private static int count = 0;
private final int id = count++;
private final int serviceTime;
public Customer(int serviceTime) {
this.serviceTime = serviceTime;
}
public int getServiceTime() {
return serviceTime;
}
@Override
public String toString() {
return "Customer_" + id;
}
}
class CustomerLine extends ArrayBlockingQueue<Customer> {
private static final long serialVersionUID = 1L;
public CustomerLine(int capacity) {
super(capacity);
}
@Override
public String toString() {
if (this.size() == 0) {
return "[Empty]";
}
StringBuilder sb = new StringBuilder();
sb.append("[ ");
for (Customer c : this) {
sb.append(c);
sb.append(" ");
}
sb.append("] ");
return sb.toString();
}
}
class GenrCustomer implements Runnable {
CustomerLine line;
Random random = new Random();
public GenrCustomer(CustomerLine line) {
this.line = line;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
TimeUnit.MILLISECONDS.sleep(random.nextInt(300));
line.put(new Customer(random.nextInt(500)));
}
} catch (InterruptedException e) {
System.out.println("模擬顧客來辦理業務被打斷 。。。。");
}
System.out.println("模擬顧客來辦理業務結束!!!");
}
}
class Teller implements Comparable<Teller>, Runnable {
private static int count = 0;
private final int id = count++;
private boolean serviceCustomer = true;
private int serviceNum = 0;
CustomerLine line;
public Teller(CustomerLine line) {
this.line = line;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
Customer customer = line.take();
TimeUnit.MILLISECONDS.sleep(customer.getServiceTime());
synchronized (this) {
serviceNum++;
if (!serviceCustomer) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(this + ",業務員服務被打斷 。。。。");
}
System.out.println(this + " ,業務員已經離開!!!");
}
public synchronized void doOtherThing() {
serviceCustomer = false;
serviceNum = 0;
}
public synchronized void serviceCustomer() {
serviceCustomer = true;
notify();
}
@Override
public int compareTo(Teller teller) {
return serviceNum > teller.serviceNum ? 1 : (serviceNum == teller.serviceNum ? 0 : -1);
}
@Override
public String toString() {
return "Teller_" + id;
}
}
class TellerManager implements Runnable {
private PriorityQueue<Teller> workerQueue = new PriorityQueue<Teller>();
private Queue<Teller> doOtherThingQueue = new LinkedList<Teller>();
ExecutorService service;
CustomerLine line;
public TellerManager(ExecutorService service, CustomerLine line) {
this.service = service;
this.line = line;
Teller teller = new Teller(line);
workerQueue.add(teller);
service.execute(teller);
service.execute(this);
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
TimeUnit.MILLISECONDS.sleep(1000);
adJust();
System.out.println(line + " { ");
for (Teller teller : workerQueue) {
System.out.println(teller + " ");
}
System.out.println("}");
}
} catch (InterruptedException e) {
System.out.println("業務員管理系統被打斷。。。");
}
System.out.println("業務員管理系統結束!!!");
}
private void adJust() {
if (line.size() / workerQueue.size() > 2) {
if (doOtherThingQueue.size() > 0) {
Teller teller = doOtherThingQueue.remove();
teller.serviceCustomer();
workerQueue.add(teller);
} else {
Teller teller = new Teller(line);
workerQueue.add(teller);
service.execute(teller);
}
return;
}
if (line.size() / workerQueue.size() < 2) {
if (workerQueue.size() > 1) {
signalTeller();
}
}
if (line.size() == 0) {
while (workerQueue.size() > 1) {
signalTeller();
}
}
}
private void signalTeller() {
Teller teller = workerQueue.remove();
teller.doOtherThing();
doOtherThingQueue.add(teller);
}
}
控制檯輸出:
[ Customer_5 ] {
Teller_0
}
[ Customer_7 Customer_8 Customer_9 Customer_10 Customer_11 Customer_12 Customer_13 ] {
Teller_1
Teller_0
}
[ Customer_14 Customer_15 Customer_16 Customer_17 Customer_18 ] {
Teller_1
Teller_0
}
[ Customer_24 ] {
Teller_0
}
[ Customer_27 ] {
Teller_0
}
[ Customer_32 Customer_33 ] {
Teller_1
Teller_0
}
[ Customer_36 Customer_37 Customer_38 ] {
Teller_0
}
[ Customer_42 Customer_43 Customer_44 ] {
Teller_1
Teller_0
}
業務員管理系統被打斷。。。
業務員管理系統結束!!!
Teller_0,業務員服務被打斷 。。。。
模擬顧客來辦理業務被打斷 。。。。
模擬顧客來辦理業務結束!!!
Teller_1,業務員服務被打斷 。。。。
Teller_1 ,業務員已經離開!!!
Teller_0 ,業務員已經離開!!!
從輸出中可以看到達到了想要的效果,這些代碼我都沒加註釋,只是希望大家能自己練習,實在弄不懂了可以聯繫我,我可以幫你解釋下。