多線程學習使用(一)——仿真之銀行業務系統

    聲明:文章內容全都是自己的學習總結,如有不對的地方請大家幫忙指出。有需要溝通交流的可加我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 ,業務員已經離開!!!
從輸出中可以看到達到了想要的效果,這些代碼我都沒加註釋,只是希望大家能自己練習,實在弄不懂了可以聯繫我,我可以幫你解釋下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章