天天看點

java多線程程式設計_Java 多線程程式設計

線程池

1、線程池,其實就是一個容納多個線程的容器,其中的線程可以反複使用,省去了頻繁建立線程對象的操作,無需反複建立線程而消耗過多資源。(是什麼)

2、那麼,我們為什麼需要用到線程池呢?每次用的時候手動建立不行嗎?

在java中,如果每個請求到達就建立一個新線程,開銷是相當大的。在實際使用中,建立和銷毀線程花費的時間和消耗的系統資源都相當大,甚至可能要比在處理實際的使用者請求的時間和資源要多的多。除了建立和銷毀線程的開銷之外,活動的線程也需要消耗系統資源。如果在一個jvm裡建立太多的線程,可能會使系統由于過度消耗記憶體或“切換過度”而導緻系統資源不足。為了防止資源不足,需要采取一些辦法來限制任何給定時刻處理的請求數目,盡可能減少建立和銷毀線程的次數,特别是一些資源耗費比較大的線程的建立和銷毀,盡量利用已有對象來進行服務。(為什麼)

線程池主要用來解決線程生命周期開銷問題和資源不足問題。通過對多個任務重複使用線程,線程建立的開銷就被分攤到了多個任務上了,而且由于在請求到達時線程已經存在,是以消除了線程建立所帶來的延遲。這樣,就可以立即為請求服務,使用應用程式響應更快;另外,通過适當的調整線程中的線程數目可以防止出現資源不足的情況。(什麼用)

3、線程池都是通過線程池工廠建立,再調用線程池中的方法擷取線程,再通過線程去執行任務方法。

Executors:線程池建立工廠類

public static ExecutorServicenewFixedThreadPool(int nThreads):傳回線程池對象

ExecutorService:線程池類

Future> submit(Runnable task):擷取線程池中的某一個線程對象,并執行

Future 接口:用來記錄線程任務執行完畢後産生的結果。線程池建立與使用

4、這裡介紹兩種使用線程池建立線程的方法

1):使用Runnable接口建立線程池

使用線程池中線程對象的步驟:

1、建立線程池對象

2、建立 Runnable 接口子類對象

3、送出 Runnable 接口子類對象

4、關閉線程池

Test.java 代碼如下:

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class Test {

public static void main(String[] args) {

//建立線程池對象 參數5,代表有5個線程的線程池

ExecutorService service = Executors.newFixedThreadPool(5);

//建立Runnable線程任務對象

TaskRunnable task = new TaskRunnable();

//從線程池中擷取線程對象

service.submit(task);

System.out.println("----------------------");

//再擷取一個線程對象

service.submit(task);

//關閉線程池

service.shutdown();

}

}

TaskRunnable.java 接口檔案如下:

public class TaskRunnable implements Runnable{

@Override

public void run() {

for (int i = 0; i < 1000; i++) {

System.out.println("自定義線程任務在執行"+i);

}

}

}

2)使用Callable接口建立線程池

Callable接口:與Runnable接口功能相似,用來指定線程的任務。其中的call()方法,用來傳回線程任務執行完畢後的結果,call方法可抛出異常。

ExecutorService:線程池類

Future submit(Callable task):擷取線程池中的某一個線程對象,并執行線程中的 call() 方法

Future 接口:用來記錄線程任務執行完畢後産生的結果。線程池建立與使用

使用線程池中線程對象的步驟:

1、建立線程池對象

2、建立 Callable 接口子類對象

3、送出 Callable 接口子類對象

4、關閉線程池

Test.java 代碼如下:

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class Test{

public static void main(String[] args) {

ExecutorService service = Executors.newFixedThreadPool(3);

TaskCallable c = new TaskCallable();

//線程池中擷取線程對象,調用run方法

service.submit(c);

//再擷取一個

service.submit(c);

//關閉線程池

service.shutdown();

}

}

TaskCallable.java 接口檔案如下:

import java.util.concurrent.Callable;

public class TaskCallable implements Callable{

@Override

public Object call() throws Exception {

for (int i = 0; i < 1000; i++) {

System.out.println("自定義線程任務在執行"+i);

}

return null;

}

}

dg5uw

dg5uw

159***[email protected]年前 (2018-03-05)

繼續閱讀