Java基礎:多執行緒之執行緒池
阿新 • • 發佈:2019-01-04
1.執行緒池的概念與Executors類的應用
應用需求:如果訪問伺服器的客戶端很多,那麼伺服器要不斷的建立和銷燬執行緒,這將嚴重的影響伺服器的效能
解決方法:首先建立一些執行緒,它們的集合稱為執行緒池,當伺服器接受到一個客戶請求後,就從執行緒池中取出一個空閒的執行緒為之服務,服務完後不關閉該執行緒,而是將執行緒還回到執行緒池中。
建立固定大小的執行緒池;
建立快取執行緒池;
建立單一執行緒池(可以實現執行緒死掉後重新啟動,即如果執行緒死掉,會自動重現建立一個替補執行緒來接替執行任務);
注意:線上程池的程式設計模式下,任務是提交給整個執行緒池的,而不是直接交給某個執行緒;執行緒池在拿到任務後,它就在內部找有無空閒的執行緒,再把任務交給某個空閒的執行緒,這就是封裝。記住,任務是提交給整個執行緒池的,一個執行緒同時只能執行一個任務,但可同時向一個執行緒池提交多個任務。
2.關閉執行緒池
shutdown與shutdownNow的比較:
shutdown: 啟動一次順序關閉,執行以前提交的任務,但不接受新任務。
shutdownNow: 試圖停止所有正在執行的活動任務,暫停處理正在等待的任務,並返回等待執行的任務列表。
3.用執行緒池啟動定時器
ScheduledExecutorService newScheduledThreadPool(int corePoolSize):
建立一個執行緒池,它可安排在給定延遲後執行命令或者定期地執行。
演示程式碼如下:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class ThreadPool {
public static void main(String[] args){
threadPoolTest();
//scheduledThreadPoolTest();
}
private static void threadPoolTest() {
//1.建立一個可重用固定執行緒數的執行緒池,以共享的無界佇列方式來執行這些執行緒
//ExecutorService threadPool=Executors.newFixedThreadPool(3);
//2.建立一個可根據需要建立新執行緒的執行緒池,但是在以前構造的執行緒可用時將重用它們
//ExecutorService threadPool=Executors.newCachedThreadPool();
//3.建立一個使用單個 worker 執行緒的 Executor,以無界佇列方式來執行該執行緒
ExecutorService threadPool=Executors.newSingleThreadExecutor();
for(int i=1;i<=10;i++){
final int taskNum=i;
threadPool.execute(new Runnable(){//十個任務,但始終只有三個執行緒
public void run(){
System.out.println(Thread.currentThread().getName()+" is running ..... for task "+taskNum);
}
});
}
//沒有新的任務到來,執行緒就會等待,執行緒不死,程式就不會結束,除非顯示shutdown
threadPool.shutdown();
// 試圖停止所有正在執行的活動任務,暫停處理正在等待的任務,即立即關閉
//threadPool.shutdownNow();
}
private static void scheduledThreadPoolTest() {
Runnable r=new Runnable(){
@Override
public void run() {
System.out.println("bombing......");
}
};
//10秒後執行
//ScheduledFuture<?> sf=Executors.newScheduledThreadPool(3).schedule(r, 10, TimeUnit.SECONDS);
//4秒後開始執行,每2秒執行一次
Executors.newScheduledThreadPool(3).scheduleAtFixedRate(r, 4, 2, TimeUnit.SECONDS);
}
}