当前位置:网站首页>深入了解JUC並發(八)線程池
深入了解JUC並發(八)線程池
2022-07-20 16:03:00 【我覺得海星_98】
線程池
基礎
池化技術
我們需要 優化資源 的使用 池化技術。如線程池、JDBC的連接池、內存池、對象池等。
事先准備好一些資源,如果有人要用,就來我這裏拿,用完之後還給我,以此來提高效率
優勢
- 方便管理(管理線程)
- 降低資源的消耗(線程複用)
- 提高響應的速度(控制最大並發數)
工作原理
三大方法
- 單個線程:ExecutorService threadPool = Executors.newSingleThreadExecutor();
- 創建一個固定的線程池的大小:ExecutorService threadPool = Executors.newFixedThreadPool(5);
- 可伸縮的(大小可變):ExecutorService threadPool = Executors.newCachedThreadPool();
代碼
//工具類 Executors 三大方法;
public class Demo01 {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();//單個線程
ExecutorService threadPool2 = Executors.newFixedThreadPool(5); //創建一個固定的線程池的大小
ExecutorService threadPool3 = Executors.newCachedThreadPool(); //可伸縮的
//線程池用完必須要關閉線程池
try {
for (int i = 1; i <=100 ; i++) {
//通過線程池創建線程
//new Thread().start(); 不用此方法
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+ " ok");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
threadPool.shutdown();
}
}
}
七大參數
源碼分析
public ThreadPoolExecutor(int corePoolSize, //核心線程池大小
int maximumPoolSize, //最大的線程池大小
long keepAliveTime, //超時了沒有人調用就會釋放
TimeUnit unit, //超時單比特
BlockingQueue<Runnable> workQueue, //阻塞隊列
ThreadFactory threadFactory, //線程工廠 創建線程的 一般不用動
RejectedExecutionHandler handler //拒絕策略
) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
- corePoolSize(必需):核心線程數。默認情况下,核心線程會一直存活,但是當將 allowCoreThreadTimeout 設置為 true 時,核心線程也會超時回收。
- maximumPoolSize(必需):線程池所能容納的最大線程數。當活躍線程數達到該數值後,後續的新任務將會阻塞。
- keepAliveTime(必需):線程閑置超時時長。如果超過該時長,非核心線程就會被回收。如果將 allowCoreThreadTimeout 設置為 true 時,核心線程也會超時回收。
- unit(必需):指定 keepAliveTime 參數的時間單比特。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
- workQueue(必需):任務隊列。通過線程池的 execute() 方法提交的 Runnable 對象將存儲在該參數中。其采用阻塞隊列實現。
- threadFactory(可選):線程工廠。用於指定為線程池創建新線程的方式。
- handler(可選):拒絕策略。當達到最大線程數時需要執行的飽和策略。
理解
代碼
注意:阿裏巴巴的Java操作手册中明確說明,對於Integer.MAX_VALUE初始值較大,所以一般情况我們要使用底層的ThreadPoolExecutor來創建線程池
public class PollDemo {
public static void main(String[] args) {
ExecutorService service =new ThreadPoolExecutor(
2,//核心線程池大小(銀行一直會存在的業務窗口)
5,//核心線程池大小(銀行最大的業務窗口:有3個候客區滿了會開)
3,//超時數值(除核心窗口以外的窗口,3s會自動釋放)
TimeUnit.SECONDS,//超時單比特(秒)
new LinkedBlockingDeque<>(3),//阻塞隊列,長度為3(相當於是候客區有3個座比特)
Executors.defaultThreadFactory(),//線程工廠
new ThreadPoolExecutor.AbortPolicy()//拒絕策略(銀行滿了,還有人進來,不處理這個人的,並拋出异常)
);
try {
//只有線程1 2運行
for (int i = 1; i <= 5; i++) {
//線程1 2 3 4 5都會運行
//for (int i = 1; i <= 8; i++) {
//拋出异常
//for (int i = 1; i <= 9; i++) {
service.execute(() -> {
System.out.println(Thread.currentThread().getName() + "ok");
});
}
}catch (Exception e) {
e.printStackTrace();
}
finally {
service.shutdown();
}
}
}
拒絕策略
- AbortPolicy(默認):丟弃任務並拋出RejectedExecutionException异常
- CallerRunsPolicy:由調用線程處理該任務
- DiscardPolicy:丟弃任務,但是不拋出异常。可以配合這種模式進行自定義的處理方式
- DiscardOldestPolicy:丟弃隊列最早的未處理任務,然後重新嘗試執行任務
設置線程池的大小
- CPU密集型:根據電腦核數(最大發揮電腦性能)
// 獲取cpu 的核數
int max = Runtime.getRuntime().availableProcessors();
ExecutorService service =new ThreadPoolExecutor(
2,
max,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
- I/O密集型:判斷我們程序中十分耗I/O的線程數量,假設在程序中有15個大型任務,大約是最大I/O數的一倍到兩倍之間(30)
边栏推荐
- 2022 Henan League game 2: Henan University of Technology
- [LSTM regression prediction] Based on MATLAB attention mechanism, LSTM time series regression prediction [including Matlab source code, 1992]
- [introduction series of redis] get to know redis and the installation of redis
- 有奖互动|7.19数据库升舱计划实战峰会:行业领袖齐聚,他们因何而来?
- 面试官:说一下Redis和MongoDB的区别?[通俗易懂]
- 吃透Chisel语言.19.Chisel组合电路(一)——Chisel组合电路与Chisel条件语句
- DS(PatterMatchalgorithm)
- 广州深入开展经营性自建房安全整治“百日行动” 两个月排查房屋逾两百万栋
- Xcelium XRUN用户手册
- 【LSTM回归预测】基于matlab attention机制LSTM时间序列回归预测【含Matlab源码 1992期】
猜你喜欢
RISC-V MCU 物联网智能外卖柜
Bi skills - same month on month calculation
[ERROR] COLLATION ‘utf8_unicode_ci‘ is not valid for CHARACTER SET ‘latin1‘
uni-app - Refused to display ‘xxx‘ in a frame because an ancestor violates the following Content Sec
[matlab project practice] Research on UAV image compression technology based on region of interest
MySQL数据库优化的这几种方式你都知道吗?
About the development of chain game system (analysis and description of the principle of smart contract uplink) - Analysis and cases of the development principle of NFT chain game system
Only 22 years old! This Post-00 doctor plans to work in 985 universities!
【SCADA案例】mySCADA助力Vib公司实现产线现代化升级
面试必问之项目的组成
随机推荐
[LSTM regression prediction] Based on MATLAB attention mechanism, LSTM time series regression prediction [including Matlab source code, 1992]
通达信炒股怎样线上开户?有没有安全上的问题??
QGIS mosaic tile grid data
PG數據庫安裝timescale數據庫以及備份配置
【SCADA案例】mySCADA助力Vib公司实现产线现代化升级
What is the difference between shallow copy and deep copy?
吃透Chisel语言.17.Chisel模块详解(四)——用函数实现轻量级模块
C语言深度剖析笔记2
Only 22 years old! This Post-00 doctor plans to work in 985 universities!
[常用工具] 基于psutil和GPUtil获取系统状态信息
MySQL eight part essay, preparing for the golden nine silver ten
What does DNS hijacking mean? What are the common hijackings?
Omnipeek 抓包工具
UVM in UVM_ Usage with parameters in event
DS(LineLinkStorStruct)
【ARM】新唐NUC977移植WK2124驱动
Summary of word operation methods in VIM
Use octree structure to manage scenes
有奖互动|7.19数据库升舱计划实战峰会:行业领袖齐聚,他们因何而来?
浅析MySQL中concat及group_concat的使用