線程池類結構
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,新任務都不排隊而是直接添加新線程。
2.池中線程數大於等於corePoolSize,workQueue未滿,將新任務加入workQueue而不是添加新線程。
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