1. 程式人生 > >Executors建立的4種執行緒池的使用

Executors建立的4種執行緒池的使用

Java通過Executors提供四種執行緒池,分別為:
newCachedThreadPool建立一個可快取執行緒池,如果執行緒池長度超過處理需要,可靈活回收空閒執行緒,若無可回收,則新建執行緒。
newFixedThreadPool 建立一個定長執行緒池,可控制執行緒最大併發數,超出的執行緒會在佇列中等待。
newScheduledThreadPool 建立一個定長執行緒池,支援定時及週期性任務執行。
newSingleThreadExecutor 建立一個單執行緒化的執行緒池,它只會用唯一的工作執行緒來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先順序)執行。

注意:執行緒池只是為了控制應用中處理某項業務中防止高併發問題帶來的執行緒不安全的發生的概率。在我目前的測試用,還沒有發現執行緒可以重用這個概念,因為執行緒開啟後,用完就關閉了,不可以再次開啟的,檢視原始碼發現會每次新建立一個執行緒用來處理業務。我們可以通過執行緒池指定處理這項業務最大的同步執行緒數,比如:Executors.newFixedThreadPool(3);線上程池中保持三個執行緒可以同時執行,但是注意,並不是說執行緒池中永遠都是這三個執行緒,只是說可以同時存在的執行緒數,當某個執行緒執行結束後,會有新的執行緒進來。newFixedThreadPool.execute(new

ThreadForpools());這句話的含義並不是新增新的執行緒,而是新增新的處理業務請求進來。至少我當前是這麼理解的,沒有發現執行緒可以重複使用。

處理執行緒程式碼:

package com.alivn.sockets;
/**
 * Created by Alivn on 2017/3/19.
 */
public class ThreadForpools implements Runnable{

    private Integer index;
    public  ThreadForpools(Integer index)
    {
     this.index=index;
    }
    @Override
    public void run() {
        /***
         * 業務......省略
          */
        try {
            System.out.println("開始處理執行緒!!!");
            Thread.sleep(index*100);
            System.out.println("我的執行緒標識是:"+this.toString());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

(1) newCachedThreadPool
建立一個可快取執行緒池,應用中存在的執行緒數可以無限大

示例程式碼如下:

package com.alivn.sockets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * Created by Alivn on 2017/3/19.
 */
public class Threadpools {

    /**
     * 我們獲取四次次執行緒,觀察4個執行緒地址
     * @param args
     */
    public static  void main(String[]args)
    {
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        System.out.println("****************************newCachedThreadPool*******************************");
        for(int i=0;i<4;i++)
        {
            final int index=i;
          newCachedThreadPool.execute(new ThreadForpools(index));
        }
    }
}

輸出結果是:可以有無限大的執行緒數進來(執行緒地址不一樣)

111111

(2) newFixedThreadPool
建立一個定長執行緒池,可控制執行緒最大併發數,超出的執行緒會在佇列中等待。示例程式碼如下:

package com.alivn.sockets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * Created by Alivn on 2017/3/19.
 */
public class Threadpools {

    /**
     * 我們獲取四次次執行緒,觀察4個執行緒地址
     * @param args
     */
    public static  void main(String[]args)
    {
        //執行緒池允許同時存在兩個執行緒
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(2);
        System.out.println("****************************newFixedThreadPool*******************************");
        for(int i=0;i<4;i++)
        {
            final int index=i;
            newFixedThreadPool.execute(new ThreadForpools(index));
        }
    }
}

輸出結果:每次只有兩個執行緒在處理,當第一個執行緒執行完畢後,新的執行緒進來開始處理(執行緒地址不一樣)

222

(3) newScheduledThreadPool
建立一個定長執行緒池,支援定時及週期性任務執行。延遲執行示例程式碼如下:

package com.alivn.sockets;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by Alivn on 2017/3/19.
 */
public class Threadpools {

    /**
     * 我們獲取四次次執行緒,觀察4個執行緒地址
     * @param args
     */
    public static  void main(String[]args)
    {
        ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(2);
        System.out.println("****************************newFixedThreadPool*******************************");
        for(int i=0;i<4;i++)
        {
            final int index=i;
            //延遲三秒執行
            newScheduledThreadPool.schedule(new ThreadForpools(index),3, TimeUnit.SECONDS);
        }
    }
}

執行結果:延遲三秒之後執行,除了延遲執行之外和newFixedThreadPool基本相同,可以用來執行定時任務

333

4) newSingleThreadExecutor
建立一個單執行緒化的執行緒池,它只會用唯一的工作執行緒來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先順序)執行。示例程式碼如下:

package com.alivn.sockets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by Alivn on 2017/3/19.
 */
public class Threadpools {

    /**
     * 我們獲取四次次執行緒,觀察4個執行緒地址
     * @param args
     */
    public static  void main(String[]args)
    {
        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
        System.out.println("****************************newFixedThreadPool*******************************");
        for(int i=0;i<4;i++)
        {
            final int index=i;
            newSingleThreadExecutor.execute(new ThreadForpools(index));
        }
    }
}

執行結果:只存在一個執行緒,順序執行

444