Java手寫線程池的實現(xiàn)方法
本文實例為大家分享了Java手寫線程池的實現(xiàn)代碼,供大家參考,具體內(nèi)容如下
1.線程池是一種多線程處理形式,處理過程中將任務(wù)添加到隊列,然后在創(chuàng)建線程后自動啟動這些任務(wù)。線程池線程都是后臺線程。
2.線程池簡易架構(gòu)
3.簡易線程池代碼(自行優(yōu)化)
import java.util.List; /** * 線程接口 * * @Author yjian * @Date 14:49 2017/10/14 **/ public interface IThreadPool { //加入任務(wù) void execute(Runnable task); //加入任務(wù) void execute(Runnable[] tasks); //加入任務(wù) void execute(List<Runnable> tasks); //銷毀線程 void destroy(); }
import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; /** * 線程實現(xiàn)類(簡易實現(xiàn),自行優(yōu)化.提供思路) * * @Author yjian * @Date 14:49 2017/10/14 **/ @SuppressWarnings("ALL") public class ThreadPoolImpl implements IThreadPool { //默認(rèn)開啟線程個數(shù) static int WORKER_NUMBER = 5; //完成任務(wù)線程數(shù) 可見性 static volatile int sumCount = 0; //任務(wù)隊列 list非線程安全,可以優(yōu)化為BlockingQueue static List<Runnable> taskQueue = new LinkedList<Runnable>(); //線程工作組 WorkerThread[] workThreads; //原子性 static AtomicLong threadNum = new AtomicLong(); static ThreadPoolImpl threadPool; //構(gòu)造方法 public ThreadPoolImpl() { this(WORKER_NUMBER); } public ThreadPoolImpl(int workerNum) { this.WORKER_NUMBER = workerNum; //開辟工作線程空間 workThreads = new WorkerThread[WORKER_NUMBER]; //開始創(chuàng)建工作線程 for (int i = 0; i < WORKER_NUMBER; i++) { workThreads[i] = new WorkerThread(); Thread thread = new Thread(workThreads[i], "ThreadPool-worker" + threadNum.incrementAndGet()); System.out.println("初始化線程數(shù)" + (i + 1) + "---------當(dāng)前線程名稱:" + thread.getName()); thread.start(); } } @Override public String toString() { return "工作線程數(shù)量為" + WORKER_NUMBER + "已完成的任務(wù)數(shù)" + sumCount + "等待任務(wù)數(shù)量" + taskQueue.size(); } //獲取線程池 public static IThreadPool getThreadPool() { return getThreadPool(WORKER_NUMBER); } public static IThreadPool getThreadPool(int workerNum) { //容錯性,如果小于等于0就默認(rèn)線程數(shù) if (workerNum <= 0) { workerNum = WORKER_NUMBER; } if (threadPool == null) { threadPool = new ThreadPoolImpl(workerNum); } return threadPool; } @Override public void execute(Runnable task) { synchronized (taskQueue) { taskQueue.add(task); taskQueue.notifyAll(); } } @Override public void execute(Runnable[] tasks) { synchronized (taskQueue) { for (Runnable task : tasks) { taskQueue.add(task); } taskQueue.notifyAll(); } } @Override public void execute(List<Runnable> tasks) { synchronized (taskQueue) { for (Runnable task : tasks) { taskQueue.add(task); } taskQueue.notifyAll(); } } @Override public void destroy() { //循環(huán)是否還存在任務(wù),如果存在等待20毫秒處理時間 while (!taskQueue.isEmpty()) { try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } //如果任務(wù)隊列已處理完成,銷毀線程,清空任務(wù) for (int i = 0; i < WORKER_NUMBER; i++) { workThreads[i].setWorkerFlag(); workThreads[i] = null; } threadPool = null; taskQueue.clear(); } //創(chuàng)建工作線程池 class WorkerThread extends Thread { //用來標(biāo)識當(dāng)前線程屬于活動可用狀態(tài) private boolean isRunning = true; @Override public void run() { Runnable runnable = null; //死循環(huán) while (isRunning) { //非線程安全,所以采用同步鎖 synchronized (taskQueue) { while (isRunning && taskQueue.isEmpty()) { try { //如果任務(wù)隊列為空,等待20毫秒 監(jiān)聽任務(wù)到達(dá) taskQueue.wait(20); } catch (Exception e) { e.printStackTrace(); } } //任務(wù)隊列不為空 if (!taskQueue.isEmpty()) { runnable = taskQueue.remove(0);//獲取第一個任務(wù) } } if (runnable != null) { runnable.run(); } sumCount++; runnable = null; } } //銷毀線程 public void setWorkerFlag() { isRunning = false; } } }
import java.util.ArrayList; import java.util.List; /** * 測試類 * * @Author yjian * @Date 15:37 2017/10/14 **/ public class ThreadPoolTest { public static void main(String[] args) { //獲取線程池 IThreadPool t = ThreadPoolImpl.getThreadPool(20); List<Runnable> taskList = new ArrayList<Runnable>(); for (int i = 0; i < 100; i++) { taskList.add(new Task()); } //執(zhí)行任務(wù) t.execute(taskList); System.out.println(t); //銷毀線程 t.destroy(); System.out.println(t); } static class Task implements Runnable { private static volatile int i = 1; @Override public void run() { System.out.println("當(dāng)前處理的線程:" + Thread.currentThread().getName() + " 執(zhí)行任務(wù)" + (i++) + " 完成"); } } }
對spring源碼研究的,仔細(xì)查看代碼用了哪幾種spring常用的模式。寫程序的規(guī)范應(yīng)該和spring一樣。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot?@InitBinder注解綁定請求參數(shù)的過程詳解
這篇文章主要介紹了SpringBoot?@InitBinder注解綁定請求參數(shù),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04JDK17、JDK19、JDK1.8輕松切換(無坑版,小白也可以看懂!)
在做不同的java項目時候,因項目需要很可能來回切換jdk版本,下面這篇文章主要介紹了JDK17、JDK19、JDK1.8輕松切換的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02springboot+jwt+微信小程序授權(quán)登錄獲取token的方法實例
本文主要介紹了springboot+jwt+微信小程序授權(quán)登錄獲取token的方法實例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03Java中Boolean與字符串或者數(shù)字1和0的轉(zhuǎn)換實例
下面小編就為大家?guī)硪黄狫ava中Boolean與字符串或者數(shù)字1和0的轉(zhuǎn)換實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07Postman實現(xiàn)傳List<String>集合
這篇文章主要介紹了Postman實現(xiàn)傳List<String>集合方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08jxl 導(dǎo)出數(shù)據(jù)到excel的實例講解
下面小編就為大家分享一篇jxl 導(dǎo)出數(shù)據(jù)到excel的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12