Java中的線程池以及Lambda表達式的應用

一、線程池

1、什麼是線程池

自定義的線程類不管是繼承Thread類還是實現Runnable接口,都需要重寫Run方法,而且每一個線程對象有且只能執行一次,之後就會被銷燬,使用起來就比較麻煩。

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

2、線程池的使用

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

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

class MyThread implements Runnable {
	@Override
	public void run() {
		System.out.println("Runnable接口實現類,線程目標代碼");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

public class Demo1 {
	public static void main(String[] args) {
		// 1. 創建線程池對象
		ExecutorService service = Executors.newFixedThreadPool(3);
		
		// 2. 創建一個MyThread Runnable接口實現類對象
		MyThread target = new MyThread();
		
		// 3. 使用線程池對象中的一個線程,指定目標代碼
		// 初始化線程數爲3,這裏使用的是線程池中已經存在的3個線程來執行代碼
		service.submit(target);
		service.submit(target);
		service.submit(target);
		
		// 因爲原本的3個線程都在被使用中,這裏需要等待3個線程執行完畢,出現空閒線程
		// 來執行對應的目標代碼
		service.submit(target);
		service.submit(target);
		
		// 4. 關閉線程池
		// 一般不用關閉線程池,會隨着程序的退出而關閉
		// service.shutdown();
	}
}
3、引入Lambda表達式

線程池的 submit() 方法需要一個Runnable接口的實現類對象,像上面直接自定義一個Runnable接口實現類比較麻煩,會想到使用匿名內部類直接傳入 submit() 方法中。其實此處使用Lambda表達式來代替匿名內部類更加簡潔。

public class Demo2 {
	public static void main(String[] args) {
		ExecutorService service = Executors.newFixedThreadPool(2);
		
		//使用匿名內部類
		service.submit(new Runnable() {
			
			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName());
			}
		}); 
			
		// 使用lambda表達式
		service.submit(() -> System.out.println(Thread.currentThread().getName())); 
	}
}

二、Lambda表達式

1、使用前提
  1. 有且只有一個缺省屬性爲public abstract方法的接口,例如 Comparator接口,Runnable接口。
  2. 使用lambda表達式是有一個前後要求約束的,方法的參數爲接口類型,或者說局部變量使用調用方法,可以使用lambda表達式。
  3. 有且只有一個抽象方法的接口,稱之爲函數式接口
2、無參數無返回值的情況
interface Cook {
	void cooking();
}

public class Demo1 {
	public static void main(String[] args) {
		//使用匿名內部類
		invokeCook(new Cook() {
			
			@Override
			public void cooking() {
				System.out.println("鍋包肉");
			}
		});
		//使用Lambda表達式,規範形式
		invokeCook(() -> {
			System.out.println("紅燒排骨");
		});
		//使用Lambda表達式,極簡形式
		invokeCook(() -> System.out.println("西紅柿炒雞蛋"));
	}
	
	/**
	 * 執行Cook實現類對象方法
	 * 
	 * @param cook Cook接口的實現類對象
	 */
	public static void invokeCook(Cook cook) {
		cook.cooking();
	}
}
3、有參數有返回值的情況
interface A {
	float add(int num1, float num2);
}

public class Demo2 {
	public static void main(String[] args) {
		//使用匿名內部類
		System.out.println(new A() {
			
			@Override
			public float add(int num1, float num2) {
				return num1 + num2;
			}
		}.add(5, 13.5F));
		
		/*
		 * 使用Lambda表達式
		 * 1. 參數的數據類型可以省略
		 * 2. 實現的代碼非一行,可以在大括號內完成所有目標
		 */
		test(5, 13.5F, (num1, num2) -> {
			float sum = num1 + num2;
			return sum;
		});	
	}
	
	public static void test(int num1, float num2, A a) {
		System.out.println(a.add(num1, num2));
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章