1. 程式人生 > >使用線程池優化多線程編程

使用線程池優化多線程編程

線程 回收 連接 eem popu sso 實例 技術 創建時間

Java中的對象是使用new操作符創建的,假設創建大量短生命周期的對象。這樣的方式性能很低下。為了解決問題,而發明了池技術。

對於數據庫連接有連接池,對於線程則有線程池。

本實例介紹兩種方式創建1000個短生命周期的線程。第一種是普通方式,另外一種是線程池的方式。通過時間和內存消耗的對照,就能夠非常明顯地看出線程池的優勢。

實例結果例如以下:

技術分享

說明:使用線程池創建對象的時間是15毫秒。說明線程池是很高效的。

關鍵技術:

Executors類為java.util.concurrent包中所定義的Executor、ExecutorService、ScheduleExecutorService、ThreadFactory和Callable類提供工廠方法和有用方法。該類支持下面各種方法:

(a)創建並返回設置有經常使用配置字符串的ExecutorService方法。

(b)創建並返回設置有經常使用配置字符串的ScheduleService方法。

(c)創建並返回“包裝的”ExecutorService方法,它通過使特定於實現的方法不可訪問來禁用 又一次配置。

(d)創建並返回ThreadFactory方法,它能夠將創建的線程設置為已知的狀態。

(e)創建並返回非閉包形式的Callable方法,這樣可將其用於須要Callable的運行方法中。

本實例使用newFixedThreadPool()方法。創建一個可重用固定線程數的線程池。它以共享的無界隊列方式來執行這些線程。

該方法的聲明例如以下:

public static ExecutorService newFixedThreadPool(int nThreads)

參數說明: nThreads為池中的線程池。

設計過程:

1)編寫類TempThread,該類實現了Runnable接口。在run()方法中。進行簡單的自增運算,代碼例如以下:

public class TempThread implements Runnable {// 測試用的Runnable接口實現類
    private int id = 0;
    
    @Override
    public void run() {// run()方法給id做自增運算
        id++;
    }
}

2)編寫類ThreadPoolTest進行測試,在main()方法中,使用兩種方式創建1000個線程,分別輸出了創建時間和占用的內存。

代碼例如以下:

</pre><pre class="java" name="code">import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolTest {
    public static void main(String[] args) {
        Runtime run = Runtime.getRuntime();// 創建Runtime對象
        run.gc();// 執行垃圾回收器,這樣能夠降低誤差
        long freeMemory = run.freeMemory();// 獲得當前虛擬機的空暇內存
        long currentTime = System.currentTimeMillis();// 獲得當前虛擬機的時間
        for (int i = 0; i < 10000; i++) {// 獨立執行1000個線程
            new Thread(new TempThread()).start();
        }
        System.out.println("獨立執行1000個線程所占用的內存:" + (freeMemory - run.freeMemory()) + "字節");// 查看內存的變化
        System.out.println("獨立創建1000個線程所消耗的時間:" + (System.currentTimeMillis() - currentTime) + "毫秒");// 查看時間的變化
        
        run.gc();// 執行垃圾回收器
        freeMemory = run.freeMemory();// 獲得當前虛擬機的空暇內存
        currentTime = System.currentTimeMillis();// 獲得當前虛擬機的時間
        ExecutorService executorService = Executors.newFixedThreadPool(2);// 創建線程池
        for (int i = 0; i < 1000; i++) {// 使用線程池執行1000個線程
            executorService.submit(new TempThread());
        }
        System.out.println("使用連接池執行1000個線程所占用的內存:" + (freeMemory - run.freeMemory()) + "字節");// 查看內存的變化
        System.out.println("使用連接池創建1000個線程所消耗的時間:" + (System.currentTimeMillis() - currentTime) + "毫秒");// 查看時間的變化
    }
}

註意:在使用完線程池後,須要調用ExecutorService接口中定義的shutdownNow()方法,來終止線程池。


使用線程池優化多線程編程