1. 程式人生 > 實用技巧 >執行緒池&lambda表示式

執行緒池&lambda表示式

基礎題

練習一:執行緒池概念

問題:

請描述什麼是執行緒池。

答:

執行緒池:其實就是一個容納多個執行緒的容器,其中的執行緒可以反覆使用,省去了頻繁建立執行緒物件的操作,無需反覆建立執行緒而消耗過多資源。

練習二:執行緒池優點

問題:

請描述合理利用執行緒池能夠帶來三個好處

答:

1. 降低資源消耗。減少了建立和銷燬執行緒的次數,每個工作執行緒都可以被重複利用,可執行多個任務。

2. 提高響應速度。當任務到達時,任務可以不需要的等到執行緒建立就能立即執行。

3. 提高執行緒的可管理性。可以根據系統的承受能力,調整執行緒池中工作線執行緒的數目,防止因為消耗過多的記憶體,而把伺服器累趴下

(每個執行緒需要大約1MB記憶體,執行緒開的越多,消耗的記憶體也就越大,最後宕機)

練習三:Lambda表示式

問題:

請列舉Lambda語法的省略規則

答:

Lambda標準格式的基礎上,使用省略寫法的規則為:

  1. 小括號內參數的型別可以省略;
  2. 如果小括號內有且僅有一個參,則小括號可以省略;
  3. 如果大括號內有且僅有一個語句,則無論是否有返回值,都可以省略大括號、return關鍵字及語句分號。

練習四:Lambda表示式

問題:

請列舉Lambda表示式的3個組成部分,並解釋說明。

答:

Lambda標準格式 Lambda省去面向物件的條條框框,格式由3個部分組成:一些引數,一個箭頭,一段程式碼。

Lambda表示式的標準格式為:格式說明:

  1. 小括號內的語法與傳統方法引數列表一致:無引數則留空;多個引數則用逗號分隔。
  2. ->是新引入的語法格式,代表指向動作。
  3. 大括號內的語法與傳統方法體要求基本一致。

練習五:Lambda表示式

問題:

請描述Lambda的使用前提

答:

Lambda的語法非常簡潔,完全沒有面向物件複雜的束縛。但是使用時有幾個問題需要特別注意:

1. 使用Lambda必須具有介面,且要求介面中有且僅有一個抽象方法。無論是JDK內建的 Runnable Comparator 介面還是自定義的介面,只有當介面中的抽象方法存在且唯一時,才可以使用Lambda

2. 使用

Lambda必須具有上下文推斷。也就是方法的引數或區域性變數型別必須為Lambda對應的介面型別,才能使用Lambda作為該介面的例項。

練習六:多執行緒

問題:

請在指定位置插入程式碼實現列印輸出1-99

public class Test06 {
public int start = 1;
public int end = 99;
public static void main (String[] args) {
new Test06().method();
 }
public void method() {
//請在此處插入程式碼,實現功能
Thread t = new Thread( a );
  t.start();
 }
}  

答:

public class Test06 {
public int start = 1;
public int end = 99;

public static void main(String[] args) {
new Test06().method();
 }

public void method() {
//插入程式碼處
Runnable a = () -> {
  for (int i = start; i <end; i++) {
    System.out.println(i);
  }
 };
  Thread t = new Thread(a);
  t.start();
 }
}

  

練習七:多執行緒

問題:給出以下程式碼,請問該程式的執行結果是什麼?如有問題,請說明原因。

public class Test07implements Runnable {
public static void main(String[] args) {
  Thread t = new Thread(new Test07());
  t.start();
 }

public void run(int num) {
for (int i = 0; i < num; i++) {
   System.out.println(i);
  }
 }
}

  

答:

在編譯時期就會報錯

Test類沒有重寫Runnable介面中的run()方法

public void run(int num)不是Runnable介面中的run()方法。

注意:Runnable介面中的run()方法,引數列表為空,不帶引數。

練習八:執行緒池練習

問題:

使用執行緒池建立多執行緒。模擬同學找老師學習Java

  1. 建立執行緒池物件,包含2個執行緒。從執行緒池中獲取執行緒物件,然後呼叫MyRunnable中的run()
  2. 在MyRunnable實現類中,首先在控制檯列印需求,“我需要一個老師”。模擬需要2秒鐘時間老師可以過來指導學生,並在控制檯列印老師的姓名。最後,在控制檯列印“教我java,教完後,老師回到了辦公室”;

答:

/*
*1.Runnable實現類程式碼:
*/

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

public class MyRunnable implements Runnable {
@Override
public void run() {
  System.out.println("我要一個老師");
try {
   Thread.sleep(2000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("老師來了"+Thread.currentThread().getName());
  System.out.println("教我java,教完後,老師回到了辦公室");
 }
}

/*
*2.執行緒池測試類:
*/

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

public class ThreadPoolDemo {
public static void main(String[] args) {
// 建立執行緒池物件
ExecutorService service = Executors.newFixedThreadPool(2);//包含2個執行緒物件
// 建立Runnable例項物件
MyRunnable r = new MyRunnable();
//自己建立執行緒物件的方式
// Thread t = new Thread(r);
// t.start(); ‐‐‐>呼叫MyRunnable中的run()
// 從執行緒池中獲取執行緒物件,然後呼叫MyRunnable中的run()
service.submit(r);
// 再獲取個執行緒物件,呼叫MyRunnable中的run()
service.submit(r);
  service.submit(r);
// 注意:submit方法呼叫結束後,程式並不終止,是因為執行緒池控制了執行緒的關閉。
// 將使用完的執行緒又歸還到了執行緒池中
// 關閉執行緒池
//service.shutdown();

}
} 

練習九:Lambda(無參無返回)練習

問題:

給定一個導演Director介面,內含唯一的抽象方法makeMovie,且無引數、無返回值,使用lambda表示式在Test中完成呼叫。

public interface Director {
void makeMovie();
} 

在下面的程式碼中,請使用Lambda的省略格式呼叫 invokeDirect 方法,列印輸出“導演拍電影啦”字樣:

public class Test09InvokeDirect {
public static void main(String[] args) {
// TODO 請使用Lambda【省略格式】呼叫invokeDirect方法

 

 }

private static void invokeDirect(Director director) {
  director.makeMovie();
 }
} 

答:

l使用Lambda【省略格式】呼叫invokeDirect方法

public class Test09InvokeDirect {
public static void main(String[] args) {
// 2.在此使用Lambda【省略格式】呼叫invokeDirect方法
invokeDirect(() -> System.out.println("導演拍電影啦!"));
 }

private static void invokeDirect(Director director) {
  director.makeMovie();
 }
}

練習十:Lambda(有參有返回)練習

問題:

給定一個計算器Calculator介面,內含抽象方法calc (減法),其功能是可以將兩個數字進行相減,並返回差值。使用Lambda表示式在Test中完成呼叫。

public interface Calculator {
int calc(int a, int b);
}

  

在下面的程式碼中,請分別使用Lambda的標準格式及省略格式呼叫 invokeCalc 方法,完成130120相減計算:

public class Test10InvokeCalc {
public static void main(String[] args) {
// TODO 請分別使用Lambda【標準格式】及【省略格式】呼叫invokeCalc方法來計算130-120的結果ß

 }

private static void invokeCalc(int a, int b, Calculator calculator) {
int result = calculator.calc(a, b);
  System.out.println("結果是:" + result);
 }
}

答:

1.使用Lambda【標準格式】呼叫invokeCalc方法來計算130-120的結果ß

public class Test10InvokeCalc {
public static void main(String[] args) {
// 1.在此使用Lambda【標準格式】呼叫invokeCalc方法來計算130-120的結果ß
invokeCalc(130, 120, (int a, int b) -> {
return a - b;
  });
 }

private static void invokeCalc(int a, int b, Calculator calculator) {
int result = calculator.calc(a, b);
  System.out.println("結果是:" + result);
 }
}

2.使用Lambda省略格式】呼叫invokeCalc方法來計算130-120的結果ß

public class Test10InvokeCalc {
public static void main(String[] args) {
// 2.在此使用Lambda【省略格式】呼叫invokeCalc方法來計算130-120的結果ß
invokeCalc(130, 120, (a, b) -> a - b);
 }

private static void invokeCalc(int a, int b, Calculator calculator) {
int result = calculator.calc(a, b);
  System.out.println("結果是:" + result);
 }
}