如何去設計一個本身的線程池?
思路與生產者與消費者模式相同,將任務放到隊列中,子線程再從隊列中取出任務去執行。java
方式一:固定線程池,一開始是就申請好線程。 好比: 公司一次性僱傭5個工人,日後在接手任務仍是這5 我的去作。 import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class ThreadPoolV1{ private BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(10);//隊列容量爲10,大於就阻塞等待。 private Thread[] workers = new Thread[5];//線程的個數即一開始僱傭的工人個數 ThreadPoolV1() { for (int i = 0; i < 5; i++) { workers[i] = new Worker(workQueue); workers[i].start();//5個線程的啓動 去完成業務 } } public void execute(Runnable cmd) throws InterruptedException { workQueue.put(cmd);//將任務放到隊列中 } private static class Worker extends Thread { private BlockingQueue<Runnable> workQueue; Worker(BlockingQueue<Runnable> queue) { workQueue = queue; } @Override public void run() { while (!isInterrupted()) { try { Runnable cmd = workQueue.take();//從隊列中把任務取出來 cmd.run();//業務 } catch (InterruptedException e) { break; } } } } public static void main(String[] args) throws InterruptedException { ThreadPoolV1 pool = new ThreadPoolV1(); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第一個事情"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第二個時期"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第三 個時期"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) System.out.println("第四個時期"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第五個時期"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第五個時期"); } } }); }
```
方式二:當有任務時僱傭一個工人,再來任務時再僱傭一個工人,一直這樣,直到僱傭人數達到預期最大值,再來任務就放到隊列中去。ide
public class ThreadPoolV2 { private BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(10);//隊列上大於10個任務時,發生阻塞等待 private int maxThreads = 5; private int currentThreads = 0;//一開始沒有線程 private Thread[] works = new Thread[maxThreads]; public void execute(Runnable cmd) throws InterruptedException { if (currentThreads == maxThreads) {//僱傭人數達到最大值 workQueue.put(cmd);//任務放到隊列 } else { Worker worker = new Worker(workQueue);//僱傭一個工人 works[currentThreads++] = worker; worker.start(); workQueue.put(cmd); } } private static class Worker extends Thread { private BlockingQueue<Runnable> workQueue; Worker(BlockingQueue<Runnable> queue) { workQueue = queue; } @Override public void run() { while (!isInterrupted()) { try { Runnable cmd = workQueue.take();//從 cmd.run(); } catch (InterruptedException e) { break; } } } } } public static void main(String[] args) throws InterruptedException { ThreadPoolV1 pool = new ThreadPoolV1(); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第一個事情"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第二個時期"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第三 個時期"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第四個時期"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第五個時期"); } } }); pool.execute(new Runnable() { @Override public void run() { while (true) { System.out.println("第六個時期"); } } }); } }