java多線程之線程池(ExecutorService)

  建立新線程的服務器在建立和銷燬線程上花費的時間和消耗的系統資源要比花在處理實際的用戶請求的時間和資源更多,線程池爲線程生命週期開銷問題和資源不足問題提供瞭解決方案。經過對多個任務重用線程,線程建立的開銷被分攤到了多個任務上。 其好處是,由於在請求到達時線程已經存在,因此無心中也消除了線程建立所帶來的 延遲。這樣,就能夠當即爲請求服務,使應用程序響應更快。並且,經過適當地調整 線程池中的線程數目,也就是當請求的數目超過某個閾值時,就強制其它任何新到的請求一直等待,直到得到一個線程來處理爲止,從而能夠防止資源不足。緩存

示例代碼:服務器

ThreadPoolTest類:dom

  1.  
    public class ThreadPoolTest {
  2.  
     
  3.  
    //單一線程數:就是隻有一個線程開啓,若是多長執行的話就是,這個線程一直輪詢執行下去
  4.  
    @SuppressWarnings("unused")
  5.  
    private ExecutorService executorService1 = Executors.newSingleThreadExecutor();
  6.  
    //固定線程數:在程序初始化的時候,虛擬機初始化5個線程
  7.  
    @SuppressWarnings("unused")
  8.  
    private ExecutorService executorService2 = Executors.newFixedThreadPool(5);
  9.  
    //緩存線程數:在程序初始化的時候建立5線程線程,並隨着系統的需求增長線程數量,線程數量的上限是系統資源的上線
  10.  
    private ExecutorService executorService3 = Executors.newScheduledThreadPool(5);
  11.  
     
  12.  
    private static int num = 50;
  13.  
    public void threadPool() throws InterruptedException {
  14.  
    //建立了50個線程
  15.  
    for(int i = 0; i < 50; i ++) {
  16.  
     
  17.  
    executorService3.execute( new Runnable() {
  18.  
    public void run() {
  19.  
    try {
  20.  
    Thread.sleep( new Random().nextInt(1700));
  21.  
    } catch (InterruptedException e) {
  22.  
    // TODO Auto-generated catch block
  23.  
    e.printStackTrace();
  24.  
    }
  25.  
    finish();
  26.  
    System.out.println(Thread.currentThread().getName() + "當前剩餘任務數量:" + (num));
  27.  
    }
  28.  
    });
  29.  
    }
  30.  
    }
  31.  
    public synchronized void finish() {
  32.  
    num--;
  33.  
    if(num == 0) {
  34.  
    System.out.println( "線程池全部任務執行完畢");
  35.  
    }
  36.  
    }
  37.  
    }

Main類:測試

  1.  
    public class Main {
  2.  
     
  3.  
    public static void main(String[] args) throws Exception {
  4.  
    System.out.println( "-----------threadPool測試-----------------");
  5.  
    new ThreadPoolTest().threadPool();
  6.  
    }

測試結果:spa

能夠看到5個線程在執行50個任務,只要線程池裏有空閒線程,就會使該線程執行任務。線程

另外,還能夠經過實現Runnable接口,使用線程池ExecutorService的submit方法來向線程池提交任務。3d

示例代碼:code

ThreadPoolSubmit類:blog

  1.  
    public class ThreadPoolSubmit implements Runnable{
  2.  
     
  3.  
    private static int num = 50;
  4.  
     
  5.  
    public void run() {
  6.  
     
  7.  
    try {
  8.  
    Thread.sleep( new Random().nextInt(1700));
  9.  
    } catch (InterruptedException e) {
  10.  
    // TODO Auto-generated catch block
  11.  
    e.printStackTrace();
  12.  
    }
  13.  
    finish();
  14.  
    System.out.println(Thread.currentThread().getName() + "當前剩餘任務數量:" + (num));
  15.  
    }
  16.  
     
  17.  
    public synchronized void finish() {
  18.  
    num--;
  19.  
    if(num == 0) {
  20.  
    System.out.println( "線程池全部任務執行完畢");
  21.  
    }
  22.  
    }
  23.  
     
  24.  
    public static void main(String[] args) {
  25.  
     
  26.  
    ExecutorService executorService = Executors.newScheduledThreadPool( 5);
  27.  
    //50個任務
  28.  
    for (int i = 0; i < 50; i++) {
  29.  
     
  30.  
    executorService.submit( new ThreadPoolSubmit());
  31.  
    }
  32.  
    }
  33.  
     
  34.  
    }

測試結果與上例相同。接口

相關文章
相關標籤/搜索