1. 程式人生 > >Java線程池應用

Java線程池應用

ati 基本 end exce 參與 廣泛 並且 exception inter

在Java中,多線程有著廣泛運用。在實際應用中,好的軟件設計不建議手動創建和銷毀線程。線程的創建和銷毀是非常耗 CPU 和內存資源的,因為這需要 JVM 和操作系統的參與。為此,我們在面臨多線程問題時,通常會采用線程池。一般情況下,每個線程池會由這些模塊組成:一個任務隊列,一個工作線程的集合,一個線程工廠,管理線程狀態的元數據。

線程池可以解決兩個問題:一是由於減少了每個任務調用的開銷,它們通常可以在執行大量異步任務時提供增強的性能,並且還可以提供綁定和管理資源(包括執行任務集時使用的線程)的方法;二是每個 ThreadPoolExecutor 還維護著一些基本的統計數據,如完成的任務數。

線程池均位於 java.util.concurrent包中。

ThreadPoolExecutor類的繼承關系為:

public class ThreadPoolExecutor extends AbstractExecutorService

其中,抽象類 AbstractExecutorService的繼承關系為:

public abstract class AbstractExecutorService extends Object implements ExecutorService

ExecutorService接口的繼承關系為:

public interface ExecutorService extends Executor

Executor是一個頂級接口。

在實際應用中,我們可以采用Executors的工廠方法Executors.newCachedThreadPool()(無界限程池,可以進行自動線程回收),Executors.newFixedThreadPool(int)(固定大小線程池),或Executors.newSingleThreadExecutor()(單個後臺線程)來生成線程池,這些方法生成的線程池均為大多數使用場景預定義了設置。

Executors的的繼承關系為:

public class Executors extends Object

由於創建子線程可以有繼承Thread類,實現Runnable接口,以及實現Callable接口三種方式,所以,我這裏先通過這三種方式創建線程,然後再通過一個測試類通過線程池來運行。

MyThread.java中的代碼如下:

public class MyThread extends Thread{
	public MyThread(String name){
 super(name);
	}
	int num=10;
	@Override
	public void run() {
 while(num>=0){
 try {
 Thread.sleep(100);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 System.out.println(getName()+"正在數:"+num);
 num--;
 }
	}
}

MyRun.java中的代碼如下:

public class MyRun implements Runnable { public MyRun(String name){ Thread.currentThread().setName(name); } int num=10; @Override public void run() { while(num>=0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"正在數:"+num); num--; } } }

MyCall.java中的代碼如下:

public class MyCall implements Callable<String> {
	int num=10;
	@Override
	public String call() throws Exception {
 while(num>=0){
 try {
 Thread.sleep(100);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 System.out.println(Thread.currentThread().getName()+"正在數:"+num);
 num--;
 }
 return Thread.currentThread().getName()+"順利執行";
	}
}

測試文件Test.java中的代碼如下:

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class Test {
	//采用newFixedThreadPool()方法創建線程池,設置線程池中有2個線程
	static ThreadPoolExecutor pool=(ThreadPoolExecutor) Executors.newFixedThreadPool(2);
	//或者采用下述方式生成線程連接池
//	static ExecutorService pool=Executors.newFixedThreadPool(2);	
	public static void main(String[] args) {
 Future<String> s1 = pool.submit(new MyCall());
 Future<String> s2 = pool.submit(new MyCall());
 try {
 System.out.println(s1.get());
 System.out.println(s2.get());
 } catch (InterruptedException e) {
 e.printStackTrace();
 } catch (ExecutionException e) {
 e.printStackTrace();
 }
 //切記:線程池不是線程執行結束就終止,而是手動終止
 pool.shutdown();
	}
	public static void main2(String[] args) {
 pool.submit(new MyRun("張三"));
 pool.submit(new MyRun("李四"));
 pool.submit(new MyRun("王五"));
 pool.submit(new MyRun("趙六"));
 //切記:線程池不是線程執行結束就終止,而是手動終止
 pool.shutdown();
	}	
	public static void main1(String[] args) {
 pool.submit(new MyThread("張三"));
 pool.submit(new MyThread("李四"));
 pool.submit(new MyThread("王五"));
 pool.submit(new MyThread("趙六"));
 //切記:線程池不是線程執行結束就終止,而是手動終止
 pool.shutdown();
	}
}

Java線程池應用