Java多執行緒(十三):執行緒池
阿新 • • 發佈:2019-09-17
執行緒池類結構
1.Executor是頂級介面,有一個execute方法。
2.ExecutorService介面提供了管理執行緒的方法。
3.AbstractExecutorService管理普通執行緒,SchedulerExecutorService管理定時任務。
簡單的示例
public class MyThread46 { public static void main(String[] args) { long startTime = System.currentTimeMillis(); final List<Integer> l = new LinkedList<Integer>(); ThreadPoolExecutor tp = new ThreadPoolExecutor(100, 100, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(20000)); final Random random = new Random(); for (int i = 0; i < 20000; i++) { tp.execute(new Runnable() { public void run() { l.add(random.nextInt()); } }); } tp.shutdown(); try { tp.awaitTermination(1, TimeUnit.DAYS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() - startTime); System.out.println(l.size()); } }
執行結果如下
52
19919
ThreadPoolExecutor七個引數
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
1.corePoolSize
執行緒池當前可以存在的執行緒數量
2.maximumPoolSize
執行緒池允許的最大執行緒數量
3.keepAliveTime
當執行緒數量比corePoolSize大時才會起作用,終止前的空餘執行緒等待的最長時間。
4.unit
keepAliveTime的時間單位
5.workQueue
儲存未被執行的任務
6.threadFactory
executor建立新執行緒時使用的工廠
7.handler
當執行被阻塞時使用handler
corePoolSize與maximumPoolSize的關係
1.池中執行緒數小於corePoolSize,新任務都不排隊而是直接新增新執行緒。
3.池中執行緒數大於等於corePoolSize,workQueue已滿,但是執行緒數小於maximumPoolSize,新增新的執行緒來處理被新增的任務。
4.池中執行緒數大於等於corePoolSize,workQueue已滿,並且執行緒數大於等於maximumPoolSize,新任務被拒絕,使用handler處理被拒絕的任務。
Executors
1.newSingleThreadExecutos() 單執行緒執行緒池
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
來新任務就排隊,workQueue採用了無界佇列LinkedBlockingQueue
示例程式碼如下
public class MyThread47{
static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
public static void main(String[] args) {
for(int i =0;i<10;i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}
執行結果如下
0
1
2
3
4
5
6
7
8
9
2.newFixedThreadPool(int nThreads) 固定大小執行緒池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
固定大小執行緒池和單執行緒執行緒池類似,可以手動指定執行緒數量
示例程式碼如下
public class MyThread48 {
public static void main(String[] args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}
執行結果如下
0
1
2
3
4
5
6
8
7
9
3.newCachedThreadPool() 無界執行緒池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
有多少任務來直接執行,執行緒池最大數量Integer.MAX_VALUE,60s自動回收空閒執行緒。
示例程式碼如下
public class MyThread49 {
public static void main(String[] args) {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(index);
}
});
}
}
}
執行結果如下
0
1
2
3
4
5
6
7
8
9