執行異步任務的時候,如果隻是new Thread,存在一下弊端
a. 每次new Thread建立對象性能差。
b. 線程缺乏統一管理,可能無限制建立線程,互相之間競争,及可能占用過多系統資源導緻當機或oom。
c. 缺乏更多功能,如定時執行、定期執行、線程中斷。
Java本身提供了四種線程池
newCachedThreadPool
建立一個可緩存的線程池。如果線程池的大小超過了處理任務所需要的線程,
那麼就會回收部分空閑(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智
能的添加新線程來處理任務。此線程池不會對線程池大小做限制,線程池大小完全依賴于
作業系統(或者說JVM)能夠建立的最大線程大小。
newCachedThreadPool是存在記憶體溢出安全隐患的,因為我們假設建立的線程都在工
作,newCachedThreadPool 隻會重用空閑并且可用的線程,是以當所需線程數量足夠大
時,會不停地建立新線程,在 64-bit JDK 1.7 中 -Xss 預設是 1024k,也就是 1M(一個線
程占用的空間大小),那就是需要 10000*1M = 10G 的堆外記憶體空間來給線程使用,就 會
發生OOM
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(index * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(index);
}
});
newFixedThreadPool
建立一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待
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(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
newScheduledThreadPool
建立一個定長線程池,支援定時及周期性任務執行
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);
newSingleThreadExecutor
建立一個單線程化的線程池,它隻會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
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(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
相對于直接new Thread,線程池具有一下優點
a. 重用存在的線程,減少對象建立、消亡的開銷,性能佳。
b. 可有效控制最大并發線程數,提高系統資源的使用率,同時避免過多資源競争,避免堵塞。
c. 提供定時執行、定期執行、單線程、并發數控制等功能