多線程線程池和自定義線程池 - 簡書
https://www.jianshu.com/p/0d548f0646fc
(1條消息)Java線程池ThreadPoolExecutor及自定義線程池_Java_零度的博客專欄-CSDN博客
https://blog.csdn.net/zmx729618/article/details/78839284
線程池參數
corePoolSize:線程池核心線程數量,核心線程不會被回收,即使沒有任務執行,也會保持空閒狀態。
maximumPoolSize:線程池允許最大的線程數,當線程數量達到corePoolSize,且workQueue隊列塞滿任務了之後,繼續創建線程,優先級提高。
keepAliveTime:超過corePoolSize之後的存活時間。
unit:keepAliveTime的單位。
workQueue:當前線程數超過corePoolSize時,新的任務會處在等待狀態,並存在workQueue中,BlockingQueue是一個先進先出的阻塞式隊列實現,底層實現會涉及Java併發的AQS機制,有關於AQS的相關知識,我會單獨寫一篇,敬請期待。
threadFactory:創建線程的工廠類
handler:線程池執行拒絕策略.當線數量達到maximumPoolSize大小,並且workQueue也已經塞滿了任務的情況下,線程池會調用handler拒絕策略來處理請求。
拓展:
常見的拒絕策略:
AbortPolicy:爲線程池默認的拒絕策略,該策略直接拋異常處理。
DiscardPolicy:直接拋棄不處理。
DiscardOldestPolicy:丟棄隊列中最老的任務。
CallerRunsPolicy:將任務分配給當前執行execute方法線程來處理。
在線程池的基礎上,自定義線程池
ThreadPoolExecutor
Executors.newFixedThreadPool(10);
Executors.newCachedThreadPool();
Executors.newSingleThreadExecutor();
Executors.newWorkStealingPool();
Executors.newScheduledThreadPool(10);
newCachedThreadPool()源碼
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
newFixedThreadPool()源碼
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
共同點:
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
依據源碼自定義線程池:
new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
自定義線程,實現Runnable
public class MyTask implements Runnable {
//自定義線程ID
private int taskId;
//線程名稱
private String taskName;
public MyTask(int taskId, String taskName) {
this.taskId = taskId;
this.taskName = taskName;
}
public int getTaskId() {
return taskId;
}
public void setTaskId(int taskId) {
this.taskId = taskId;
}
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public void run() {
try {
System.out.println("當前線程Id-->" + taskId + ",任務名稱-->" + taskName);
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
main函數
public class CustomerThreadPool {
public static void main(String[] args) {
//這裏使用的是有界隊列,不是無界隊列
ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 2, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3));
MyTask task1 = new MyTask(1, "任務1");
MyTask task2 = new MyTask(2, "任務2");
MyTask task3 = new MyTask(3, "任務3");
MyTask task4 = new MyTask(4, "任務4");
MyTask task5 = new MyTask(5, "任務5");
MyTask task6 = new MyTask(6, "任務6");
pool.execute(task1);
pool.execute(task2);
pool.execute(task3);
pool.execute(task4);
pool.execute(task5);
}
}
當前線程Id-->5,任務名稱-->任務5
當前線程Id-->1,任務名稱-->任務1
當前線程Id-->2,任務名稱-->任務2
當前線程Id-->3,任務名稱-->任務3
當前線程Id-->4,任務名稱-->任務4
原因在於,新建的有界隊列只有3,除去當前執行的進程,線程池還能存放3個進程,因此當線程5放入的時候,隊列滿,則會新建線程去執行,優先級提高
真·自定義線程池
(1條消息)Java線程池ThreadPoolExecutor及自定義線程池_Java_零度的博客專欄-CSDN博客
https://blog.csdn.net/zmx729618/article/details/78839284