<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 自定義一個簡單的線程池 ## 寫在前面 在學習這個的時候,我一直在想,怎樣理清思路,把中間的點一個一個串起來,然后自己默寫出來,所以這個筆記我改了很多次,之前整理了很多理論知識,比如為什么使用線程池?線程池的優點等等,后來都刪掉了。理論知識google一下,百度一下都寫得非常好,所以我這里也沒必要copy一份粘貼在這里,這里就以理清思路為主。 ### 搭建一個最簡單的框架 這里先把最基本的代碼寫出來,我們先定義一個SimpleThreadPool類。 成員屬性兩個: **size**: *線程池里線程的數量* **DEFAULT_SIZE**: *默認線程池的線程數量* 成員方法: 兩個構造方法,這里只是構造SimpleThreadPool這個類的size。 然后構造完成后調用init(),我們再編寫一個init方法。 定義一個枚舉代表我們工作線程的四個狀態: **FREE**:*可以使用狀態* **RUNNING**:*正在運行狀態* **BLOCKED**:*阻塞狀態* **DEAD**:*結束狀態* 定義一個WorkerTask代表我們的工作線程,繼承Thead并重寫run方法,其中的狀態的構造等代碼暫時自行發揮即可。 ```java public class SimpleThreadPool { private final int size; private final static int DEFAULT_SIZE = 10; public SimpleThreadPool() { this(DEFAULT_SIZE); } public SimpleThreadPool(int size) { this.size = size; init(); } private void init() { } /** * 線程task狀態 */ private enum TaskState { FREE, RUNNING, BLOCKED, DEAD } /** * workTask */ private static class WorkerTask extends Thread { private volatile TaskState taskState = TaskState.FREE; //默認free狀態 /** * 獲取workTask的taskState狀態 * @return TaskState */ public TaskState getTaskState() { return this.taskState; } @Override public void run() { //TODO } /** * 關閉線程重置TaskState為DEAD */ public void close() { this.taskState = TaskState.DEAD; } } } ``` ### 完善工作線程邏輯 接下來開始一步一步完善程序: 1. WorkerTask中引入ThreadGroup ```java public WorkerTask(ThreadGroup threadGroup,String name){ super(threadGroup,name); } ``` 2. 接下來完善run方法,因為run方法不能執行完程序就掛掉,如果執行完就掛掉了也就沒意義了,所以這里使用while: ```java @Override public void run() { while(this.taskState != TaskState.DEAD){ //TODO 執行任務 } } ``` 3. 接下來就要考慮我們執行的任務在哪里獲取呢?這里就要用到任務隊列了: ```java private final static LinkedList<Runnable> TASK_QUEUE = new LinkedList<>(); ``` 完善我們的while循環: ```java @Override public void run() { while (this.taskState != TaskState.DEAD) { synchronized (TASK_QUEUE) { // 任務隊列為空,則進入阻塞狀態 while (TASK_QUEUE.isEmpty()) { try { this.taskState = TaskState.BLOCKED; TASK_QUEUE.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } ``` 注意看這個位置: ![](https://img.kancloud.cn/f9/16/f91696af27c0aa18dfc87b08fb1a0c4e_610x334.png) 如果我們在任務隊列為空的情況下,打斷wait()的線程是退出到while循環里的,所以我們要加一個lable: ![](https://img.kancloud.cn/ba/ef/baef3d5574b1accb862d94c31c14ace5_598x332.png) 4. 接下來我們編寫**任務隊列不為空**情況下的代碼: ```java @Override public void run() { OUTER: while (this.taskState != TaskState.DEAD) { synchronized (TASK_QUEUE) { Runnable runnable; // 任務隊列為空,則進入阻塞狀態 while (TASK_QUEUE.isEmpty()) { try { this.taskState = TaskState.BLOCKED; TASK_QUEUE.wait(); } catch (InterruptedException e) { System.out.println("Closed."); break OUTER; } } // 任務隊列不為空,取出任務 runnable = TASK_QUEUE.removeFirst(); // 任務不為空,則執行任務 if (runnable != null) { this.taskState = TaskState.RUNNING; runnable.run(); this.taskState = TaskState.FREE; } } } } ``` 5.這樣工作線程就定義完了,接下來就要完善提交任務了,在提交任務之前,我們首先要構建。 我們在SimpleThreadPool類里面增加creatWorkeTask方法: ```java private void creatWorkeTask(String name) { } ``` 這里我們打算用creatWorkeTask調用WorkerTask,WorkerTask的兩個參數,一個線程組,一個名字,這個名字我們來通過前綴+自增的方式生成,所以: (注意這里是volatile) ```java private static volatile int seg=0; ``` 增加名字的前綴 ```JAVA /** * 線程名前綴 */ private final static String THREAD_PREFIX = "SIMPLE_THREAD_POOL-"; ``` 增加一個ThreadGroup: ```java /** * 線程組 */ private final static ThreadGroup GROUP = new ThreadGroup("Pool_Group"); ``` 這樣就開始完善我們的creatWorkeTask方法了: ```java private void creatWorkeTask(String name) { WorkerTask task = new WorkerTask(GROUP,THREAD_PREFIX+(seg++)); task.start(); THREAD_QUEUE.add(task); } ``` 這里start后我們把他放在線程隊列里,我們定義一個List來存放WorkerTask,以便于我們管理。 ```java /** * 線程隊列 */ private static final List<WorkerTask> THREAD_QUEUE = new ArrayList<>(); ``` 6.提交任務我們就寫到這里,現在開始編寫init方法: ```java private void init() { for (int i = 0; i < size; i++) { creatWorkeTask(); } } ``` 7.這時候我們如果調用SimpleThreadPool,他去init的時候,其實WorkerTask是wait狀態,因為TASK_QUEUE是空的,這時候我們就需要一個對外開放的接口來操作TASK_QUEUE了: (這里有個細節就是因為TASK_QUEUE在我們的工作隊列里是有讀操作的,所以我們這里要加鎖才行) ```java public void submit(Runnable runnable){ synchronized (TASK_QUEUE){ TASK_QUEUE.addLast(runnable); TASK_QUEUE.notifyAll(); } } ``` 8.接下來就是激動人心的時刻,我們簡單調用一下看看效果: ```java public static void main(String[] args) { SimpleThreadPool threadPool = new SimpleThreadPool(); IntStream.rangeClosed(0, 40) .forEach(i -> { threadPool.submit(() -> { System.out.println("The Runnable" + i + " be serviced by " + Thread.currentThread().getName()+" start"); try { Thread.sleep(1_000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("The Runnable" + i + " be serviced by " + Thread.currentThread().getName()+" finished"); }); }); } ``` 9.補充一點,注意看這里的代碼: ![](https://img.kancloud.cn/28/03/28033994d5530de8669cce9c00d6520e_729x482.png) 調整后的代碼如下: ![](https://img.kancloud.cn/9d/91/9d91ae423ce82148645098345b1bd5f2_578x467.png) 看一下運行效果: ![](https://img.kancloud.cn/5a/2d/5a2dcc3b9f098fe47c36dbe7eeaee46d_1053x349.gif) 一共10個線程,執行了40個任務,后面我們再繼續完善線程池,增加拒絕策略,停止等功能。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看