午夜剧场伦理_日本一道高清_国产又黄又硬_91黄色网战_女同久久另类69精品国产_妹妹的朋友在线

您的位置:首頁技術(shù)文章
文章詳情頁

java實(shí)現(xiàn)手寫一個(gè)簡單版的線程池

瀏覽:40日期:2023-02-10 14:47:07

有些人可能對線程池比較陌生,并且更不熟悉線程池的工作原理。所以他們在使用線程的時(shí)候,多數(shù)情況下都是new Thread來實(shí)現(xiàn)多線程。但是,往往良好的多線程設(shè)計(jì)大多都是使用線程池來實(shí)現(xiàn)的。 為什么要使用線程 降低資源的消耗。降低線程創(chuàng)建和銷毀的資源消耗。提高響應(yīng)速度:線程的創(chuàng)建時(shí)間為T1,執(zhí)行時(shí)間T2,銷毀時(shí)間T3,免去T1和T3的時(shí)間提高線程的可管理性

下圖所示為線程池的實(shí)現(xiàn)原理:調(diào)用方不斷向線程池中提交任務(wù);線程池中有一組線程,不斷地從隊(duì)列中取任務(wù),這是一個(gè)典型的生產(chǎn)者-消費(fèi)者模型。

java實(shí)現(xiàn)手寫一個(gè)簡單版的線程池

要實(shí)現(xiàn)一個(gè)線程池,有幾個(gè)問題需要考慮:

隊(duì)列設(shè)置多長?如果是無界的,調(diào)用方不斷往隊(duì)列中方任務(wù),可能導(dǎo)致內(nèi)存耗盡。如果是有界的,當(dāng)隊(duì)列滿了之后,調(diào)用方如何處理? 線程池中的線程個(gè)數(shù)是固定的,還是動(dòng)態(tài)變化的? 每次提交新任務(wù),是放入隊(duì)列?還是開新線程 當(dāng)沒有任務(wù)的時(shí)候,線程是睡眠一小段時(shí)間?還是進(jìn)入阻塞?如果進(jìn)入阻塞,如何喚醒?

針對問題4,有3種做法:

不使用阻塞隊(duì)列,只使用一般的線程安全的隊(duì)列,也無阻塞/喚醒機(jī)制。當(dāng)隊(duì)列為空時(shí),線程池中的線程只能睡眠一會兒,然后醒來去看隊(duì)列中有沒有新任務(wù)到來,如此不斷輪詢。 不使用阻塞隊(duì)列,但在隊(duì)列外部,線程池內(nèi)部實(shí)現(xiàn)了阻塞/喚醒機(jī)制 使用阻塞隊(duì)列

很顯然,做法3最完善,既避免了線程池內(nèi)部自己實(shí)現(xiàn)阻塞/喚醒機(jī)制的麻煩,也避免了做法1的睡眠/輪詢帶來的資源消耗和延遲。現(xiàn)在來帶大家手寫一個(gè)簡單的線程池,讓大家更加理解線程池的工作原理

實(shí)戰(zhàn):手寫簡易線程池

根據(jù)上圖可以知道,實(shí)現(xiàn)線程池需要一個(gè)阻塞隊(duì)列+存放線程的容器

/** * Five在努力 * 自定義線程池 */public class ThreadPool { /** 默認(rèn)線程池中的線程的數(shù)量 */ private static final int WORK_NUM = 5; /** 默認(rèn)處理任務(wù)的數(shù)量 */ private static final int TASK_NUM = 100; /** 存放任務(wù) */ private final BlockingQueue<Runnable> taskQueue; private final Set<WorkThread> workThreads;//保存線程的集合 private int workNumber;//線程數(shù)量 private int taskNumber;//任務(wù)數(shù)量 public ThreadPool(){this(WORK_NUM , TASK_NUM); } public ThreadPool(int workNumber , int taskNumber) {if (taskNumber<=0){ taskNumber = TASK_NUM;}if (workNumber<=0){ workNumber = WORK_NUM;}this.taskQueue = new ArrayBlockingQueue<Runnable>(taskNumber);this.workNumber = workNumber;this.taskNumber = taskNumber;workThreads = new HashSet<>();//工作線程準(zhǔn)備好了//啟動(dòng)一定數(shù)量的線程數(shù),從隊(duì)列中獲取任務(wù)處理for (int i=0;i<workNumber;i++) { WorkThread workThread = new WorkThread('thead_'+i); workThread.start(); workThreads.add(workThread);} } /** * 線程池執(zhí)行任務(wù)的方法,其實(shí)就是往BlockingQueue中添加元素 * @param task */ public void execute(Runnable task) {try { taskQueue.put(task);} catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace();} } /** * 銷毀線程池 */ public void destroy(){System.out.println('ready close pool...');for (WorkThread workThread : workThreads) { workThread.stopWorker(); workThread = null;//help gc}workThreads.clear(); } /** 內(nèi)部類,工作線程的實(shí)現(xiàn) */ private class WorkThread extends Thread{public WorkThread(String name){ super(); setName(name);}@Overridepublic void run() { while (!interrupted()) {try { Runnable runnable = taskQueue.take();//獲取任務(wù) if (runnable !=null) {System.out.println(getName()+' ready execute:'+runnable.toString());runnable.run();//執(zhí)行任務(wù) } runnable = null;//help gc} catch (Exception e) { interrupt(); e.printStackTrace();} }}public void stopWorker(){ interrupt();} }}

上面代碼定義了默認(rèn)的線程數(shù)量和默認(rèn)處理任務(wù)數(shù)量,同時(shí)用戶也可以自定義線程數(shù)量和處理任務(wù)數(shù)量。用BlockingQueue阻塞隊(duì)列來存放任務(wù)。用set來存放工作線程,set的好處就不用多說了。懂的都懂

構(gòu)造方法中new對象的時(shí)候,循環(huán)啟動(dòng)線程,并把線程放入set中。WorkThread實(shí)現(xiàn)Thread,run方法實(shí)現(xiàn)也很簡單,因?yàn)橛幸粋€(gè)stop方法,所以這里需要while判斷,之后從taskQueue隊(duì)列中,獲取任務(wù)。如何獲取不到就阻塞,獲取到的話runnable.run();就執(zhí)行任務(wù),之后把任務(wù)變成null

銷毀線程只需要遍歷set,把每個(gè)線程停止,并且變?yōu)閚ull就行了

執(zhí)行線程任務(wù)execute,只需要從往阻塞隊(duì)列中添加任務(wù)就行了

測試一下:

public class TestMySelfThreadPool { private static final int TASK_NUM = 50;//任務(wù)的個(gè)數(shù) public static void main(String[] args) {ThreadPool myPool = new ThreadPool(3,50);for (int i=0;i<TASK_NUM;i++) { myPool.execute(new MyTask('task_'+i));} } static class MyTask implements Runnable{private String name;public MyTask(String name) { this.name = name;}public String getName() { return name;}public void setName(String name) { this.name = name;}@Overridepublic void run() { try {Thread.sleep(1000); } catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace(); } System.out.println('task :'+name+' end...');}@Overridepublic String toString() { // TODO Auto-generated method stub return 'name = '+name;} }}

java實(shí)現(xiàn)手寫一個(gè)簡單版的線程池

結(jié)果ok。沒什么問題

到此這篇關(guān)于java實(shí)現(xiàn)手寫一個(gè)簡單版的線程池的文章就介紹到這了,更多相關(guān)java 手寫線程池內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 中文字幕在线观看的网站 | 超级碰97| 九九在线观看免费高清版 | 欧美日韩视频在线播放 | 国产一区二区毛片 | 免费看h| 99热免费在线观看 | 狠狠综合 | 国产福利二区 | 午夜tv | 国产精品国产三级国产普通话蜜臀 | av免费网址 | 免费黄色高清视频 | 国产成人一区二区三区影院在线 | 欧美一级在线播放 | 欧美天堂在线视频 | 国内精品偷拍 | 91福利视频在线观看 | 国产三级小视频 | 国产精品50页 | 玖玖视频在线 | 4色av| 黄色a网站| 538精品在线观看 | 欧美在线91 | 精品久久久久久久久久久久 | 免费高清成人 | 日韩av中字 | 国产亚洲精品久久久久动 | 中文字幕国产 | 糖心vlog在线免费观看 | 久久黄色精品视频 | 单身男女免费观看国语高清 | 国产亚洲精品久久久久久豆腐 | 亚洲欧美另类在线 | 亚洲成人激情在线 | 午夜视频免费在线 | 久久一级黄色片 | 欧美一级免费 | 国产成人精品av | 天天国产视频 |