java bus Java并發(fā)——阿里架構(gòu)師
一、創(chuàng)建線程
1.創(chuàng)建普通對(duì)象,只是在JVM的堆里分配一塊內(nèi)存而已
2.創(chuàng)建線程,需要調(diào)用操作系統(tǒng)內(nèi)核的API,然后操作系統(tǒng)需要為線程分配一系列資源,成本很高
線程是一個(gè)重量級(jí)對(duì)象,應(yīng)該避免頻繁創(chuàng)建和銷毀,采用線程池方案
二、一般的池化資源
// 假設(shè)Java線程池采用一般意義上池化資源的設(shè)計(jì)方法
class ThreadPool {
// 獲取空閑線程
Thread acquire() {
}
// 釋放線程
void release(Thread t) {
}
}
// 期望的使用
ThreadPool pool;
Thread T1 = pool.acquire();
// 傳入Runnable對(duì)象
T1.execute(() -> {
// 具體業(yè)務(wù)邏輯
});
三、生產(chǎn)者-消費(fèi)者模式
業(yè)界線程池的設(shè)計(jì),普遍采用生產(chǎn)者-消費(fèi)者模式,線程池的使用方是生產(chǎn)者,線程池本身是消費(fèi)者
public class MyThreadPool {
// 工作線程負(fù)責(zé)消費(fèi)任務(wù)并執(zhí)行任務(wù)
class WorkerThread extends Thread {
@Override
public void run() {
// 循環(huán)取任務(wù)并執(zhí)行
while (true) {
Runnable task = null;
try {
task = workQueue.take();
} catch (InterruptedException e) {
}
task.run();
}
}
}
// 利用阻塞隊(duì)列實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者模式
private BlockingQueue workQueue;
// 內(nèi)部保存工作線程
List threads = new ArrayList<>();
public MyThreadPool(int poolSize, BlockingQueue workQueue) {
this.workQueue = workQueue;
for (int i = 0; i < poolSize; i++) {
WorkerThread work = new WorkerThread();
work.start();
threads.add(work);
}
}
// 提交任務(wù)
public void execute(Runnable command) throws InterruptedException {
workQueue.put(command);
}
public static void main(String[] args) throws InterruptedException {
// 創(chuàng)建有界阻塞隊(duì)列
BlockingQueue workQueue = new LinkedBlockingQueue<>(2);
// 創(chuàng)建線程池
MyThreadPool pool = new MyThreadPool(10, workQueue);
// 提交任務(wù)
pool.execute(() -> {
System.out.println("hello");
});
}
}
四、Java線程池
Ⅰ. ThreadPoolExecutor
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
// 讓所有線程都支持超時(shí),如果線程池很閑,那么將撤銷所有線程
public void allowCoreThreadTimeOut(boolean value)
1.corePoolSize:線程池保有的最小線程數(shù)
2.maximumPoolSize:線程池創(chuàng)建的最大線程數(shù)
3.keepAliveTime & unit
如果一個(gè)線程空閑了keepAliveTime & unit,并且線程池的線程數(shù)大于corePoolSize,那么這個(gè)空閑的線程就要被回收
4.workQueue:工作隊(duì)列
5.threadFactory:自定義如何創(chuàng)建線程
6.handler
線程池中的所有線程都很忙碌,并且工作隊(duì)列也滿了(工作隊(duì)列是有界隊(duì)列),此時(shí)提交任務(wù),線程池會(huì)拒絕接收
CallerRunsPolicy:提交任務(wù)的線程自己去執(zhí)行該任務(wù)
AbortPolicy:默認(rèn)的拒絕策略,拋出RejectedExecutionException
DiscardPolicy:直接丟棄任務(wù),不會(huì)拋出任何異常
DiscardOldestPolicy:丟棄最老的任務(wù),然后把新任務(wù)加入到工作隊(duì)列中
Ⅱ. Executors
1.不建議使用Executors,因?yàn)镋xecutors提供的很多默認(rèn)方法使用的是無界隊(duì)列LinkedBlockingQueue
2.在高負(fù)載的情況下,無界隊(duì)列容易導(dǎo)致OOM,而OOM會(huì)導(dǎo)致所有請(qǐng)求都無法處理
3.因此強(qiáng)烈建議使用有界隊(duì)列
Ⅲ. 拒絕策略
1.使用有界隊(duì)列,當(dāng)任務(wù)過多時(shí),線程池會(huì)觸發(fā)拒絕策略
2.線程池默認(rèn)的拒絕策略會(huì)拋出RejectedExecutionException,這是一個(gè)運(yùn)行時(shí)異常,開發(fā)時(shí)很容易忽略
3.如果線程池處理的任務(wù)非常重要,可以自定義拒絕策略
Ⅳ. 異常處理
1.使用ThreadPoolExecutor.execute()方法提交任務(wù)時(shí),如果任務(wù)在執(zhí)行過程中出現(xiàn)運(yùn)行時(shí)異常
會(huì)導(dǎo)致執(zhí)行任務(wù)的線程終止,并且無法獲得任何通知
2.因此最穩(wěn)妥的方法還是捕獲所有異常并處理
try {
// 業(yè)務(wù)邏輯
} catch (RuntimeException x) {
// 按需處理
} catch (Throwable x) {
// 按需處理
}
免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作媒體供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請(qǐng)進(jìn)一步核實(shí),并對(duì)任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對(duì)有關(guān)資料所引致的錯(cuò)誤、不確或遺漏,概不負(fù)任何法律責(zé)任。任何單位或個(gè)人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識(shí)產(chǎn)權(quán)或存在不實(shí)內(nèi)容時(shí),應(yīng)及時(shí)向本網(wǎng)站提出書面權(quán)利通知或不實(shí)情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會(huì)依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。
新聞排行榜
-
2021-01-21 11:23
-
2018-09-28 11:33
-
2018-09-28 11:33
-
2018-09-28 11:33
-
2018-09-28 11:33
新聞熱門推薦
-
2021-01-21 11:23
-
2018-09-28 11:33
-
2018-09-28 11:33
-
2018-09-28 11:33
-
2018-09-28 11:33