1. 程式人生 > 其它 >Java多執行緒優化之執行緒池的使用方法

Java多執行緒優化之執行緒池的使用方法

技術標籤:開發相關技術java多執行緒併發程式設計

Java多執行緒優化之執行緒池

java標準庫提供了ExecutorService介面表示執行緒池
建立這些執行緒池的方法都被封裝到Executors這個類

文章目錄


一、FixedThreadPool

FixedThreadPool:執行緒數固定的執行緒池

public class ThreadPoolTest01 {
    public static void main(String[
] args) { //建立一個執行緒數固定為6的執行緒池 ExecutorService es = Executors.newFixedThreadPool(6); for (int i = 0; i < 6; i++) { es.submit(new Task01("start task" + i)); } // 關閉執行緒池: es.shutdown(); } } class Task01 implements Runnable{ private
final String name; public Task01(String name) { this.name = name; } @Override public void run() { System.out.println("start task " + name); try { Thread.sleep(1000); } catch (InterruptedException e) { } System.out.println
("end task " + name); } }

執行後:

start task start task0
start task start task3
start task start task1
start task start task2
start task start task4
start task start task5
end task start task3
end task start task2
end task start task5
end task start task1
end task start task4
end task start task0

二、CachedThreadPool

CachedThreadPool:執行緒數根據任務動態調整的執行緒池

public class ThreadPoolTest02 {
    public static void main(String[] args) {
        ExecutorService es = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            es.submit(new Task02("start task" + i));
        }
        es.shutdown();
    }
}

class Task02 implements Runnable{
    private final String name;

    public Task02(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("start task " + name);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        System.out.println("end task " + name);
    }
}

執行後:

start task start task0
start task start task1
start task start task2
start task start task3
start task start task4
end task start task1
end task start task0
end task start task3
end task start task4
end task start task2

如果想控制執行緒池的大小呢?首先看一下Executors.newCachedThreadPool()方法的原始碼:
MAX_VALUE = 0x7fffffff

/**
     * Creates a thread pool that creates new threads as needed, but
     * will reuse previously constructed threads when they are
     * available.  These pools will typically improve the performance
     * of programs that execute many short-lived asynchronous tasks.
     * Calls to {@code execute} will reuse previously constructed
     * threads if available. If no existing thread is available, a new
     * thread will be created and added to the pool. Threads that have
     * not been used for sixty seconds are terminated and removed from
     * the cache. Thus, a pool that remains idle for long enough will
     * not consume any resources. Note that pools with similar
     * properties but different details (for example, timeout parameters)
     * may be created using {@link ThreadPoolExecutor} constructors.
     *
     * @return the newly created thread pool
     */
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

可以這樣實現:

int min = 5;
int max = 10;
ExecutorService es = new ThreadPoolExecutor(min, max,
        60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());

第一個引數min 表示這個執行緒池初始化了5個執行緒在裡面工作
第二個引數max 表示如果5個執行緒不夠用了,就會自動增加到最多10個執行緒
第三個引數60 結合第四個引數TimeUnit.SECONDS,表示經過60秒,多出來的執行緒還沒有接到活兒,就會回收,最後保持池子裡就5個
第四個引數TimeUnit.SECONDS 如上
第五個引數 new LinkedBlockingQueue() 用來放任務的集合

三、SingleThreadExecutor

SingleThreadExecutor:僅單執行緒執行的執行緒池
適用場景:任務需要定期反覆執行

public class ThreadPoolTest03 {
    public static ScheduledExecutorService ses = Executors.newScheduledThreadPool(4);

    public static void main(String[] args) {
        //一秒後執行一次性任務
        ses.schedule(new Task03("one-time"), 1, TimeUnit.SECONDS);
        //2秒後開始執行定時任務,每3秒執行  
        //FixedRate是指任務總是以固定時間間隔觸發,不管任務執行多長時間
        ses.scheduleAtFixedRate(new Task03("fixed-rate"), 2, 3, TimeUnit.SECONDS);
        //2秒後開始執行定時任務,以3秒為間隔執行 
        //FixedDelay是指,上一次任務執行完畢後,等待固定的時間間隔,再執行下一次任務
        ses.scheduleWithFixedDelay(new Task03("fixed-delay"),2,3,TimeUnit.SECONDS);
    }

}
class Task03 implements Runnable{
    private final String name;

    public Task03(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("start task " + name);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        System.out.println("end task " + name);
    }
}

注意

執行緒池在程式執行完必須要關閉
1.呼叫shutdown()時,執行緒池的狀態則立刻變成SHUTDOWN狀態。此時,則不能再往執行緒池中新增任何任務,否則將會丟擲RejectedExecutionException異常。
2.呼叫awaitTermination()則會等待指定的時間讓執行緒池關閉。