手写一个简单的线程池MyThreadPool
生活随笔
收集整理的這篇文章主要介紹了
手写一个简单的线程池MyThreadPool
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
說明
手寫的一個簡單的線程池,旨在幫助了解線程池的工作原理。
核心內容
定義一個內部類去實現核心工作線程
/*** 內部類:工作的核心線程*/private final class WorkerThread extends Thread {String name;//構造方法WorkerThread(String name) {this.name = name;}@Overridepublic void run() {while (!getPoolState()) {try {Runnable task = taskQueue.take();if (task != null) {getThreadLog("任務開始執行:" + task.toString());task.run();}//釋放內存task = null;} catch (Exception e) {e.printStackTrace();}}System.out.println("線程關閉");}}使用一個阻塞隊列存放需要處理的任務列表
//存放任務執行結束的隊列private volatile BlockingQueue<Runnable> taskQueue;//記錄線程池中線程的個數private final Set<WorkerThread> workerThreadSet = new HashSet<>();完整測試代碼
package com.leo.demo.threadtest.mythreadpool;import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit;/*** @ClassName: MyThreadPool* @Description: 小的線程池模型* 1、線程池的* @Author: leo825* @Date: 2020-05-11 23:08* @Version: 1.0*/ public class MyThreadPool {//核心線程數private int corePoolSize;//最大線程數private int maximumPoolSize;//存放任務執行結束的隊列private volatile BlockingQueue<Runnable> taskQueue;//記錄線程池中線程的個數private final Set<WorkerThread> workerThreadSet = new HashSet<>();//當前存放當前線程數private int workerCount = 0;//線程池關閉狀態private volatile boolean THREADPOOL_SHUTDOWN = false;/*** 線程池構造方法,先不考慮參數校驗問題** @param corePoolSize* @param maximumPoolSize* @param taskQueue*/MyThreadPool(int corePoolSize, int maximumPoolSize, BlockingQueue<Runnable> taskQueue) {this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.taskQueue = taskQueue;//構造線程池中的線程for (int i = 0; i < corePoolSize; i++) {WorkerThread workerThread = new WorkerThread("poolThread_" + i);workerThread.start();workerThreadSet.add(workerThread);workerCount++;}}/*** 向線程池中提交任務執行結束** @param task*/public void submit(Runnable task) {if (taskQueue.offer(task)) {getThreadLog("任務執行結束添加成功: " + task.toString());} else {getThreadLog("任務執行結束添加失敗: " + task.toString());}}/*** 關閉線程池*/public void shutdown() {getThreadLog("關閉線程池");THREADPOOL_SHUTDOWN = true;}/*** 內部類:工作的核心線程*/private final class WorkerThread extends Thread {String name;//構造方法WorkerThread(String name) {this.name = name;}@Overridepublic void run() {while (!THREADPOOL_SHUTDOWN) {try {Runnable task = taskQueue.take();if (task != null) {getThreadLog("任務開始執行:" + task.toString());task.run();}//釋放內存task = null;} catch (Exception e) {e.printStackTrace();}}getThreadLog("線程關閉");}}/*** 獲取線程名和時間** @return*/public static void getThreadLog(String logContent) {StringBuffer stringBuffer = new StringBuffer();stringBuffer.append("[");stringBuffer.append(Thread.currentThread().getName());stringBuffer.append(" ");stringBuffer.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));stringBuffer.append("] ");stringBuffer.append(logContent);System.out.println(stringBuffer.toString());}/*** 測試main方法** @param args*/public static void main(String[] args) throws InterruptedException {//定義一個阻塞隊列存放任務BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>(5);//構造自己的線程池MyThreadPool threadPool = new MyThreadPool(3, 5, workQueue);//任務執行結束數量int size = 15;for (int i = 0; i < size; i++) {threadPool.submit(new Runnable() {@Overridepublic void run() {try {int times = ThreadLocalRandom.current().nextInt(2, 6);TimeUnit.SECONDS.sleep(times);getThreadLog("任務執行結束 " + this.toString() + ",執行時長:" + times + " 秒");} catch (InterruptedException e) {e.printStackTrace();}}});}//休息20秒TimeUnit.SECONDS.sleep(20);//關閉線程池,此處不管用的,待后續分析源碼threadPool.shutdown();} }測試結果如下:
[Thread-0 2020-06-09 11:32:12.698] 任務開始執行:com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@3fee733d [main 2020-06-09 11:32:12.696] 任務執行結束添加成功: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@3fee733d [main 2020-06-09 11:32:12.699] 任務執行結束添加成功: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@2a84aee7 [main 2020-06-09 11:32:12.699] 任務執行結束添加成功: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@a09ee92 [main 2020-06-09 11:32:12.699] 任務執行結束添加成功: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@30f39991 [main 2020-06-09 11:32:12.700] 任務執行結束添加成功: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@452b3a41 [main 2020-06-09 11:32:12.700] 任務執行結束添加成功: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@4a574795 [main 2020-06-09 11:32:12.700] 任務執行結束添加失敗: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@f6f4d33 [main 2020-06-09 11:32:12.701] 任務執行結束添加失敗: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@23fc625e [main 2020-06-09 11:32:12.701] 任務執行結束添加失敗: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@3f99bd52 [main 2020-06-09 11:32:12.701] 任務執行結束添加失敗: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@4f023edb [main 2020-06-09 11:32:12.702] 任務執行結束添加失敗: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@3a71f4dd [main 2020-06-09 11:32:12.703] 任務執行結束添加失敗: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@7adf9f5f [main 2020-06-09 11:32:12.703] 任務執行結束添加失敗: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@85ede7b [main 2020-06-09 11:32:12.703] 任務執行結束添加失敗: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@5674cd4d [main 2020-06-09 11:32:12.704] 任務執行結束添加失敗: com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@63961c42 [Thread-1 2020-06-09 11:32:12.709] 任務開始執行:com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@2a84aee7 [Thread-2 2020-06-09 11:32:12.711] 任務開始執行:com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@a09ee92 [Thread-0 2020-06-09 11:32:14.712] 任務執行結束 com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@3fee733d,執行時長:2 秒 [Thread-0 2020-06-09 11:32:14.714] 任務開始執行:com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@30f39991 [Thread-1 2020-06-09 11:32:16.710] 任務執行結束 com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@2a84aee7,執行時長:4 秒 [Thread-1 2020-06-09 11:32:16.711] 任務開始執行:com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@452b3a41 [Thread-2 2020-06-09 11:32:17.712] 任務執行結束 com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@a09ee92,執行時長:5 秒 [Thread-2 2020-06-09 11:32:17.712] 任務開始執行:com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@4a574795 [Thread-0 2020-06-09 11:32:17.715] 任務執行結束 com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@30f39991,執行時長:3 秒 [Thread-1 2020-06-09 11:32:19.711] 任務執行結束 com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@452b3a41,執行時長:3 秒 [Thread-2 2020-06-09 11:32:21.713] 任務執行結束 com.leo.demo.threadtest.mythreadpool.MyThreadPool$1@4a574795,執行時長:4 秒 [main 2020-06-09 11:32:32.704] 關閉線程池問題和思考
以上就是一個很小的線程池的模型,這個模型還存在很多問題。
總結
以上是生活随笔為你收集整理的手写一个简单的线程池MyThreadPool的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java的自动装箱与自动拆箱
- 下一篇: An internal error oc