執行一個異步任務你還只是以下new Thread嗎?java
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}).start();
複製代碼
new Thread的弊端以下:數據庫
Java經過Executors提供四種線程池,分別爲:緩存
Executors 主要是這個構造函數:安全
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) 複製代碼
而Executors工廠類一共能夠建立四種類型的線程池,經過Executors.newXXX便可建立。下面就分別都介紹一下把。網絡
建立一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。示例代碼以下:併發
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();
}
}
});
}
複製代碼
由於線程池大小爲3,每一個任務輸出index後sleep 2秒,因此每兩秒打印3個數字。異步
定長線程池的大小最好根據系統資源進行設置。ide
public static ExecutorService newFixedThreadPool(int nThreads){
return new ThreadPoolExecutor(nThreads,nThreads,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
複製代碼
建立一個可緩存線程池,若是線程池長度超過處理須要,可靈活回收空閒線程,若無可回收,則新建線程。示例代碼以下:函數
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);
}
});
}
複製代碼
//構造函數
public static ExecutorService newCachedThreadPool(){
return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.MILLISECONDS,new SynchronousQueue<Runnable>());
}
複製代碼
線程池爲無限大,當執行第二個任務時第一個任務已經完成,會複用執行第一個任務的線程,而不用每次新建線程。性能
建立一個單線程化的線程池,它只會用惟一的工做線程來執行任務,保證全部任務按照指定順序(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();
}
}
});
}
複製代碼
結果依次輸出,至關於順序執行各個任務。
public static ExecutorService newSingleThreadExecutor(){
return new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
複製代碼
它只會建立一條工做線程處理任務;採用的阻塞隊列爲LinkedBlockingQueue;
建立一個定長線程池,支持定時及週期性任務執行。延遲執行示例代碼以下:
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);
複製代碼
表示延遲3秒執行。
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);
複製代碼
表示延遲1秒後每3秒執行一次。
ScheduledExecutorService比Timer更安全,功能更強大
DelayQueue內部封裝了一個PriorityQueue,它會根據time的前後時間排序,若time相同則根據sequenceNumber排序;
DelayQueue也是一個無界隊列;
工做線程會從DelayQueue取已經到期的任務去執行;
執行結束後從新設置任務的到期時間,再次放回DelayQueue
默認是一個CachedThreadScheduler,用於IO密集型任務,如異步阻塞IO操做(讀寫文件、讀寫數據庫、網絡信息交互等)所使用的 Scheduler。
默認是:FixedThreadPool。用於CPU 密集型計算,即不會被 I/O 等操做限制性能的操做,例如圖形的計算,事件循環或和回調處理
在當前線程當即開始執行任務,至關於不指定線程。這是默認的 Scheduler
Android專用的,指定的操做將在 Android 主線程運行
使用指定的Executor做爲調度器
老是啓用新線程,並在新線程執行操做。
executor = new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue(), Util.threadFactory("OkHttp ConnectionPool", true));
複製代碼