1 引入線程池的原因
由於線程的生命周期中包括創建、就緒、運行、阻塞、銷毀階段,當我們待處理的任務數目較小時,我們可以自己創建幾個線程來處理相應的任務,但當有大量的任務時,由於創建、銷毀線程需要很大的開銷,運用線程池這些問題就大大的緩解了。
2 線程池的使用
我們只需要運用Executors類給我們提供的靜態方法,就可以創建相應的線程池:
public static ExecutorSevice newSingleThreadExecutor()
public static ExecutorSevice newFixedThreadPool()
public static ExecutorSevice newCachedThreadPool()
newSingleThreadExecutor返回以個包含單線程的Executor,將多個任務交給此Exector時,這個線程處理完一個任務后接着處理下一個任務,若該線程出現異常,將會有一個新的線程來替代。
newFixedThreadPool返回一個包含指定數目線程的線程池,如果任務數量多於線程數目,那么沒有沒有執行的任務必須等待,直到有任務完成為止。
newCachedThreadPool根據用戶的任務數創建相應的線程來處理,該線程池不會對線程數目加以限制,完全依賴於JVM能創建線程的數量,可能引起內存不足。
我們只需要將待執行的任務放入run方法中即可,將Runnable接口的實現類交給線程池的execute方法,作為它的一個參數,如下所示:
Executor executor = Executors.newSingleThreadExecutor(); executor.execute(new Runnable(){ public void run(){ //執行的任務 } }
如果需要給任務傳遞參數,可以通過創建一個Runnable接口的實現類來完成。
3 線程池使用的示例
下面我們通過一個實例來說明線程池的使用方法,該實例模仿子HADOOP中作業初始化過程,也即利用線程池從隊列中取出作業並對作業進行初始化,其代碼如下:

package com.yueliming.ThreadPool;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class FixedThreadPool {
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> List<Double><span style="color: #000000;"> queue; </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> ExecutorService threadPool; </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> FixedThreadPool() { queue </span>= <span style="color: #0000ff;">new</span> ArrayList<Double><span style="color: #000000;">(); </span><span style="color: #008000;">//</span><span style="color: #008000;">產生一個 ExecutorService 對象,這個對象帶有一個大小為 poolSize 的線程池,若任務數量大於 poolSize ,任務會被放在一個 queue 里順序執行。 </span> threadPool = Executors.newFixedThreadPool(5<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { FixedThreadPool outer </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> FixedThreadPool(); FixedThreadPool.Manager inner </span>= outer.<span style="color: #0000ff;">new</span><span style="color: #000000;"> Manager(); Thread consumer </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Thread(inner); Thread producer </span>= <span style="color: #0000ff;">new</span> Thread() {<span style="color: #008000;">//</span><span style="color: #008000;">用於向queue中放入數據</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() { </span><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> (queue) { </span><span style="color: #0000ff;">double</span> time =<span style="color: #000000;"> 1d; </span><span style="color: #0000ff;">long</span> startTime =<span style="color: #000000;"> System.currentTimeMillis(); </span><span style="color: #0000ff;">if</span> (System.currentTimeMillis() - startTime >=<span style="color: #000000;"> time) { startTime </span>=<span style="color: #000000;"> System.currentTimeMillis(); </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < 10; i++<span style="color: #000000;">) { queue.add((Math.random() </span>* 10000<span style="color: #000000;">)); } queue.notify(); } } } } }; consumer.start();</span><span style="color: #008000;">//</span><span style="color: #008000;">啟動守護線程,采用線程池來從queue中讀取數據</span>
producer.start();
}</span><span style="color: #0000ff;">class</span> Manager <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable { </span><span style="color: #0000ff;">int</span> num = 0<span style="color: #000000;">; </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() { </span><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> { </span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> (queue) { System.out.println(</span>"隊列的長度為:" +<span style="color: #000000;"> queue.size()); </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (queue.isEmpty()) { queue.wait(); } </span><span style="color: #0000ff;">double</span> result = queue.remove(0<span style="color: #000000;">); num</span>++<span style="color: #000000;">; System.out.println(</span>"成功從隊列中取到數據!" +<span style="color: #000000;"> num); threadPool.execute(</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> ExecutorThread(result)); } } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException t) { </span><span style="color: #0000ff;">break</span><span style="color: #000000;">; } } threadPool.shutdown(); } } </span><span style="color: #0000ff;">class</span> ExecutorThread <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable { </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">double</span><span style="color: #000000;"> value; </span><span style="color: #0000ff;">public</span> ExecutorThread(<span style="color: #0000ff;">double</span><span style="color: #000000;"> value) { </span><span style="color: #0000ff;">this</span>.value =<span style="color: #000000;"> value; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() { System.out.println(</span>"This is " + Thread.currentThread().getName() + " " +<span style="color: #000000;"> value); } }
}
其中內部類Manager為一個線程負責從隊列中獲取作業,並交給線程池去處理任務,有一個線程專門將數據放入到隊列中,也即每隔1ms向隊列中放入10個數據。
原文地址:https://www.cnblogs.com/yueliming/p/3300587.html