Java知識點——線程池

我們在之前的線程學習中,都是之間創建新的線程,顯性線程,用的時候開啓,用完銷燬,效率低且不安全
而且我們看到在阿里巴巴代碼規範規約中也是不建議顯式創建線程,建議使用線程池。

在這裏插入圖片描述

不管是繼承Thread還是遵從Runnable接口,都需要重寫Run方法,而且每一個線程對象有且只能執行一次,之後就會被銷燬。
利用Runnable接口來提供執行目標,而且藉助於Thread執行線程。

用生活中的例子來理解:

一個餐廳
服務人員
餐廳會按照餐桌比例安排服務員人數。
每一個服務員我們都可以看做是一個線程對象
需要告知服務器做什麼事情就可以了,相對於告知線程對象執行目標是什麼
當你來餐廳之前,服務員在這裏,你走之後,服務員依然在這類。

線程池 ==> 可以容納多個線程的容器

程序可以從線程池獲取線程來完成目標代碼
同時也可以將線程歸還給線程池。
省去了創建線程和銷燬線程這樣非常繁瑣的操作。節省時間。

在這裏插入圖片描述

線程池使用

public static ExecutorService newFixedThreadPool(int nThreads);
得到一個線程池對象,初始化參數是要求的當前線程池中的線程數

在這行代碼中, newFixedThreadPool是ExecutorService類中的方法
返回值是ExecutorService,參數是int類型的線程數量。
創建代碼示例爲:

ExecutorService service = Executors.newFixedThreadPool(5);

public Future submit(Runnable target);

從線程池中獲取一個線程對象,並且執行給定的Runnable接口實現類對象作爲執行目標

代碼如下:

package executors;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Thread1 implements Runnable{

	@Override
	public void run() {
		System.out.println("啓動成功");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("執行代碼成功");
	}
	
}

public class Demo1 {
	public static void main(String[] args) {
		ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
		
		
		Thread1 thread1 = new Thread1();
		
		newFixedThreadPool.submit(thread1);
		newFixedThreadPool.submit(thread1);
		newFixedThreadPool.submit(thread1);
		newFixedThreadPool.submit(thread1);
		newFixedThreadPool.submit(thread1);
		
		// 因爲原本的5個線程都在被使用中,這裏需要等待5個線程執行完畢,出現空閒線程
		// 來執行對應的目標代碼
		newFixedThreadPool.submit(thread1);
		newFixedThreadPool.submit(thread1);
		
		newFixedThreadPool.submit(new Thread1());
		newFixedThreadPool.submit(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("匿名內部類");
				
			}
		});
				
		// 4. 關閉線程池
		// 一般不用關閉線程池,會隨着程序的退出而關閉
		newFixedThreadPool.shutdown();
	}
}

ps:匿名內部類的使用雖說很香,但是還不夠香,下邊我們就要從匿名內部類引出Lambda表達式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章