日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

實現(xiàn)java簡單的線程池

瀏覽:47日期:2022-08-09 08:42:38
目錄拆分實現(xiàn)流程實現(xiàn)方式1.拒絕策略2.阻塞隊列3.線程池和工作線程策略模式對比JDK的線程池線程池的狀態(tài)轉(zhuǎn)化總結(jié)拆分實現(xiàn)流程

請看下面這張圖

實現(xiàn)java簡單的線程池

首先我們得對線程池進行一個功能拆分

Thread Pool 就是我們的線程池,t1,t2,t3代表三個線程 Blocking Queue代表阻塞隊列 main代表main方法的線程 task1,task2,task3代表要執(zhí)行的每個任務(wù)

現(xiàn)在我們梳理一下執(zhí)行的流程,注意這里是簡略版的,文章后面我會給出詳細版的

實現(xiàn)java簡單的線程池

所以此時,我們發(fā)現(xiàn)了需要創(chuàng)建幾個類,或者說幾個角色,分別是

線程池 工作線程 阻塞隊列 拒絕策略(干嘛的?就是當(dāng)線程數(shù)已經(jīng)滿了,并且阻塞隊列也滿了,還有任務(wù)想進入阻塞隊列的時候,就可以拒絕這個任務(wù))實現(xiàn)方式1.拒絕策略

/** * 拒絕策略 */@FunctionalInterfaceinterface RejectPolicy<T>{//queue就是我們自己實現(xiàn)的阻塞隊列,task是任務(wù) void reject(BlockingQueue<T> queue,T task);}2.阻塞隊列

我們需要實現(xiàn)四個方法,獲取和添加,超時獲取和超時添加,至于方法實現(xiàn)的細節(jié),我都備注了大量的注釋進行解釋。

/** * 阻塞隊列 */class BlockingQueue<T>{ //阻塞隊列 private Deque<T> queue = new ArrayDeque<>(); //鎖 private ReentrantLock lock = new ReentrantLock(); //生產(chǎn)者條件變量 private Condition fullWaitSet = lock.newCondition(); //消費者條件變量 private Condition emptyWaitSet = lock.newCondition(); //容量 private int capacity; public BlockingQueue(int capacity){this.capacity = capacity; } //帶有超時阻塞獲取 public T poll(long timeout, TimeUnit timeUnit){lock.lock();try { //將timeout統(tǒng)一轉(zhuǎn)換為納秒 long nanos = timeUnit.toNanos(timeout); while(queue.isEmpty()){try { if(nanos <= 0){//小于0,說明上次沒有獲取到,代表已經(jīng)超時了return null; } //返回值是剩余的時間 nanos = emptyWaitSet.awaitNanos(nanos);} catch (InterruptedException e) { e.printStackTrace();} } T t = queue.removeFirst(); //通知生產(chǎn)者 fullWaitSet.signal(); return t;}finally { lock.unlock();} } //阻塞獲取 public T take(){lock.lock();try{ while(queue.isEmpty()){ //如果任務(wù)隊列為空,代表線程池沒有可以執(zhí)行的內(nèi)容try { /* 也就說此時進來的線程是執(zhí)行不了任務(wù)的,所以此時emptyWaitSet消費者要進行阻塞狀態(tài) 等待下一次喚醒,然后繼續(xù)判斷隊列是否為空 */ emptyWaitSet.await();} catch (InterruptedException e) { e.printStackTrace();} } /* 代碼執(zhí)行到這里。說明任務(wù)隊列不為空,線程池就從任務(wù)隊列拿出一個任務(wù)出來執(zhí)行 也就是說把阻塞隊列的一個任務(wù)出隊 */ T t = queue.removeFirst(); /* 然后喚醒之前存放在生成者Condition休息室,因為由于之前阻塞隊列已滿,fullWaitSet才會進入阻塞狀態(tài) 所以當(dāng)阻塞隊列刪除了任務(wù),就要喚醒之前進入阻塞狀態(tài)的fullWaitSet */ fullWaitSet.signal(); //返回任務(wù) return t;}finally { lock.unlock();} } //阻塞添加 public void put(T task){lock.lock();try { while(queue.size() == capacity){ //任務(wù)隊列滿了try { System.out.println('等待加入任務(wù)隊列'+task); /* 也就說此時進來的任務(wù)是進不了阻塞隊列的,已經(jīng)滿了,所以此時生產(chǎn)者Condition要進入阻塞狀態(tài) 等待下一次喚醒,然后繼續(xù)判斷隊列是否為空 */ fullWaitSet.await();} catch (InterruptedException e) { e.printStackTrace();} } //任務(wù)隊列還未滿 System.out.println('加入任務(wù)隊列'+task); //把任務(wù)加入阻塞隊列 queue.addLast(task); /* 然后喚醒之前存放在消費者Condition休息室,因為由于之前阻塞隊列為空,emptyWaitSet才會進入阻塞狀態(tài) 所以當(dāng)阻塞隊列加入了任務(wù),就要喚醒之前進入阻塞狀態(tài)的emptyWaitSet */ emptyWaitSet.signal();}finally { lock.unlock();} } //帶超時阻塞時間添加 public boolean offer(T task,long timeout,TimeUnit timeUnit){lock.lock();try { long nanos = timeUnit.toNanos(timeout); while(queue.size() == capacity){try { if(nanos < 0){return false; } System.out.println('等待加入任務(wù)隊列'+task); //不會一直阻塞,超時就會繼續(xù)向下執(zhí)行 nanos = fullWaitSet.awaitNanos(nanos);} catch (InterruptedException e) { e.printStackTrace();} } System.out.println('加入任務(wù)隊列'+task); queue.addLast(task); emptyWaitSet.signal(); return true;}finally { lock.unlock();} } //獲取任務(wù)數(shù)量 public int size(){lock.lock();try{ return queue.size();}finally { lock.unlock();} } //嘗試添加任務(wù),如果阻塞隊列已經(jīng)滿了,就使用拒絕策略 public void tryPut(RejectPolicy<T> rejectPolicy, T task){lock.lock();try { //判斷隊列是否已滿 if(queue.size() == capacity){rejectPolicy.reject(this,task); }else{ //有空閑System.out.println('加入任務(wù)隊列'+task);queue.addLast(task);emptyWaitSet.signal(); }}finally { lock.unlock();} }}3.線程池和工作線程

我把工作線程當(dāng)成線程池的內(nèi)部類去實現(xiàn)。方便調(diào)用變量。

/** * 線程池 */class ThreadPool{ //阻塞隊列 private BlockingQueue<Runnable> taskQueue; //線程集合 private HashSet<Worker> workers = new HashSet<>(); //核心線程數(shù) private int coreSize; //獲取任務(wù)的超時時間 private long timeout; private TimeUnit timeUnit; private RejectPolicy<Runnable> rejectPolicy; public ThreadPool(int coreSize, long timeout, TimeUnit timeUnit, int queueCapacity,RejectPolicy<Runnable> rejectPolicy) {this.coreSize = coreSize;this.timeout = timeout;this.timeUnit = timeUnit;this.taskQueue = new BlockingQueue<>(queueCapacity);this.rejectPolicy = rejectPolicy; } //執(zhí)行任務(wù) public void execute(Runnable task){synchronized (workers){ if(workers.size() <= coreSize){ //當(dāng)前的線程數(shù)小于核心線程數(shù)Worker worker = new Worker(task);workers.add(worker);//讓線程開始工作,執(zhí)行它的run方法worker.start(); }else{// 1) 死等// 2) 帶超時等待// 3) 讓調(diào)用者放棄任務(wù)執(zhí)行// 4) 讓調(diào)用者拋出異常// 5) 讓調(diào)用者自己執(zhí)行任務(wù)taskQueue.tryPut(rejectPolicy,task); }} } /** * 工作線程,也就是線程池里面的線程 */ class Worker extends Thread{private Runnable task;public Worker(Runnable task){ this.task = task;}@Overridepublic void run() { //執(zhí)行任務(wù) // 1) 當(dāng) task 不為空,執(zhí)行任務(wù) // 2) 當(dāng) task 執(zhí)行完畢,再接著從任務(wù)隊列獲取任務(wù)并執(zhí)行 while (task != null || (task = taskQueue.poll(timeout, timeUnit)) != null) {try { System.out.println('正在執(zhí)行的任務(wù)' + task); task.run();} catch (Exception e) { e.printStackTrace();} finally { //代表這個任務(wù)已經(jīng)執(zhí)行完了 task = null;} } synchronized (workers) {System.out.println('worker 被移除' + this);workers.remove(this); }} }}策略模式

細心的小伙伴已經(jīng)發(fā)現(xiàn),我在拒絕策略這里使用了23種設(shè)計模式的策略模式,因為我沒有將拒絕的方式寫死,而是交給了調(diào)用者去實現(xiàn)。

對比JDK的線程池

下面是JDK自帶的線程池

實現(xiàn)java簡單的線程池

經(jīng)典的七大核心參數(shù)

corePoolSize:核心線程數(shù) queueCapacity:任務(wù)隊列容量(阻塞隊列) maxPoolSize:最大線程數(shù) keepAliveTime:線程空閑時間 TimeUnit unit:超時時間單位 ThreadFactory threadFactory:線程工程 rejectedExecutionHandler:任務(wù)拒絕處理器

實際上我們自己實現(xiàn)的也大同小異,只不過JDK官方的更為復(fù)雜。

JDK線程執(zhí)行的流程圖

實現(xiàn)java簡單的線程池

實現(xiàn)java簡單的線程池

線程池的狀態(tài)轉(zhuǎn)化

線程我們知道在操作系統(tǒng)層面有5種狀態(tài)

實現(xiàn)java簡單的線程池

初始狀態(tài):僅是在語言層面創(chuàng)建了線程對象,還未與操作系統(tǒng)線程關(guān)聯(lián) 可運行狀態(tài)(就緒狀態(tài)):指該線程已經(jīng)被創(chuàng)建(與操作系統(tǒng)線程關(guān)聯(lián)),可以由 CPU 調(diào)度執(zhí)行 運行狀態(tài):指獲取了 CPU 時間片運行中的狀態(tài),當(dāng) CPU 時間片用完,會從【運行狀態(tài)】轉(zhuǎn)換至【可運行狀態(tài)】,會導(dǎo)致線程的上下文切換 阻塞狀態(tài) 如果調(diào)用了阻塞 API,如 BIO 讀寫文件,這時該線程實際不會用到 CPU,會導(dǎo)致線程上下文切換,進入【阻塞狀態(tài)】 等 BIO 操作完畢,會由操作系統(tǒng)喚醒阻塞的線程,轉(zhuǎn)換至【可運行狀態(tài)】 與【可運行狀態(tài)】的區(qū)別是,對【阻塞狀態(tài)】的線程來說只要它們一直不喚醒,調(diào)度器就一直不會考慮調(diào)度它們 終止?fàn)顟B(tài):表示線程已經(jīng)執(zhí)行完畢,生命周期已經(jīng)結(jié)束,不會再轉(zhuǎn)換為其它狀態(tài)

線程在Java API層面有6種狀態(tài)

實現(xiàn)java簡單的線程池

NEW 線程剛被創(chuàng)建,但是還沒有調(diào)用 start() 方法 RUNNABLE 當(dāng)調(diào)用了 start() 方法之后,注意,Java API 層面的 RUNNABLE 狀態(tài)涵蓋了 操作系統(tǒng) 層面的【可運行狀態(tài)】、【運行狀態(tài)】 BLOCKED , WAITING , TIMED_WAITING 都是 Java API 層面對【阻塞狀態(tài)】的細分 TERMINATED 當(dāng)線程代碼運行結(jié)束

線程池有5種狀態(tài)

RUNNING:能接受新任務(wù),并處理阻塞隊列中的任務(wù) SHUTDOWN:不接受新任務(wù),但是可以處理阻塞隊列中的任務(wù) STOP:不接受新任務(wù),并且不處理阻塞隊列中的任務(wù),并且還打斷正在運行任務(wù)的線程,就是直接不干了! TIDYING:所有任務(wù)都終止,并且工作線程也為0,處于關(guān)閉之前的狀態(tài) TERMINATED:已關(guān)閉。

實現(xiàn)java簡單的線程池

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注好吧啦網(wǎng)的更多內(nèi)容!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品欧美久久| 精品国产成人| 日韩亚洲一区在线| 精品中文在线| 老鸭窝一区二区久久精品| 欧美日本精品| 欧美欧美黄在线二区| 国产欧美精品久久| 国产日韩欧美一区二区三区 | 久久精品观看| 久久中文字幕av| 伊人久久成人| 国产成人77亚洲精品www| 欧洲毛片在线视频免费观看| 麻豆精品91| 成人免费网站www网站高清| 亚洲精品影视| 91精品蜜臀一区二区三区在线| 国产精品亚洲综合久久| 久久国产高清| 黄色成人精品网站| 国产精品一国产精品k频道56| 亚洲精品麻豆| 国产日韩欧美三区| 国产成人精品三级高清久久91| 日韩中文首页| 亚洲精品影视| 国产成人精品999在线观看| 欧美日韩水蜜桃| 日韩美女精品| 日韩电影二区| 日韩精品一级二级| 国产精品片aa在线观看| 91精品韩国| 久久国产日韩欧美精品| 久久人人精品| 国产免费av一区二区三区| 国产精品二区不卡| 亚洲欧美视频| 黄毛片在线观看| 欧美亚洲免费| 亚洲国产一区二区在线观看| 国产精品**亚洲精品| 黄色亚洲在线| 欧美精选视频一区二区| 麻豆国产一区| 日本不卡一区二区三区| 亚洲精品成人| 日韩成人高清| 99精品电影| 在线日韩中文| 夜久久久久久| 精品免费av在线| 成人在线视频区| 精品久久不卡| 极品日韩av| 尹人成人综合网| 亚洲精选成人| 久久久久黄色| 日韩在线中文| 久久国产高清| 久久激情五月婷婷| 超碰在线99| 日韩视频在线一区二区三区| 日韩精品免费视频一区二区三区 | 中文一区一区三区免费在线观 | 欧美日韩精品免费观看视欧美高清免费大片 | 美女国产精品| 久久精品国产免费| 亚洲精品一二三**| 日本午夜精品| 久久国产麻豆精品| 精品国产18久久久久久二百| 国产99亚洲| 久久福利一区| 久久精品一区| 一区二区三区网站| 国产一区二区三区久久| 亚洲精品va| 欧美日韩午夜电影网| 日本成人在线不卡视频| 中文欧美日韩| 亚久久调教视频| 欧美日韩调教| 亚洲国产欧美日本视频| 国产成人免费av一区二区午夜| 91视频精品| 国产韩日影视精品| 97精品久久| 国产免费成人| 日本成人一区二区| av免费不卡国产观看| 99免费精品| 欧美日韩国产传媒| 日韩av中文字幕一区二区 | 婷婷综合网站| 石原莉奈在线亚洲二区| 88久久精品| 91看片一区| 日本午夜精品视频在线观看| 你懂的国产精品| 国产一区二区三区不卡视频网站| 国产日韩电影| 日韩精品亚洲专区| 亚洲v在线看| 国产欧美午夜| 久久亚洲风情| 日本精品不卡| 麻豆视频一区| 一区二区不卡| 欧美日韩一二| 精品亚洲免a| 国产精品婷婷| 色综合五月天| 国产精品亚洲二区| 视频精品一区| 日韩一区三区| 精品资源在线| 亚洲精品在线二区| 欧美午夜精彩| 亚洲福利国产| 日韩一区二区三区在线免费观看| 欧美亚洲三级| 亚洲欧美视频| 久久av在线| 日韩欧美一区二区三区在线观看 | 丝瓜av网站精品一区二区| 高清一区二区| 国产精品久av福利在线观看| 日本亚洲视频在线| 亚洲免费播放| 在线精品视频在线观看高清| 亚洲先锋成人| 九一精品国产| 99视频精品全国免费| 激情黄产视频在线免费观看| 美日韩一区二区三区| 国产精品亚洲成在人线| 日本亚洲视频| 午夜一级久久| 亚洲一区二区三区四区五区午夜 | 亚洲欧洲av| 视频一区二区中文字幕| 亚洲综合日本| 丝袜国产日韩另类美女| 9久re热视频在线精品| 欧美专区在线| 亚洲aa在线| 日本aⅴ亚洲精品中文乱码| 国产亚洲观看| 国产在线观看www| 精品欧美视频| 日韩精品欧美| 日韩中文字幕1| 欧美日韩 国产精品| 97人人精品| 视频精品一区二区| 日韩精品国产欧美| 久久久久久夜| 免费日韩av片| 91超碰国产精品| 国产精品毛片aⅴ一区二区三区| 精品视频在线你懂得| 精品入口麻豆88视频| 亚洲先锋成人| 欧美日韩黄网站| 久久久久蜜桃| 国产伦理一区| 亚洲永久字幕| 伊人久久婷婷| 亚洲二区三区不卡| 99国内精品| 亚洲性视频在线| 日韩国产在线一| 国产精品s色| 六月婷婷综合| 免费观看久久av| 中文字幕av亚洲精品一部二部| 日韩不卡一区二区三区| 亚洲97av| 日本精品黄色| 欧美成人精品| 日韩欧美2区| 精品久久97| 午夜精品一区二区三区国产| 中文字幕一区二区三区在线视频| 欧美日韩xxxx| 麻豆成人在线观看| 婷婷综合一区| 在线看片日韩| 欧美一级专区| 午夜欧美精品| 欧美日韩亚洲在线观看| a天堂资源在线| 欧美一区自拍| 国产亚洲一区| 免费看久久久| 国产精品二区不卡| 中文字幕在线视频网站| 人人精品亚洲|