練習一:線程池概念
- 問題:
- 請描述什么是線程池。
- 答:
- 線程池:其實就是一個容納多個線程的容器,其中的線程可以反復使用,省去了頻繁創(chuàng)建線程對象的操作,無需反復創(chuàng)建線程而消耗過多資源。
練習二:線程池優(yōu)點
-
問題:
- 請描述合理利用線程池能夠帶來的三個好處。
答:
1.降低資源消耗。減少了創(chuàng)建和銷毀線程的次數,每個工作線程都可以被重復利用,可執(zhí)行多個任務。
2.提高響應速度。當任務到達時,任務可以不需要的等到線程創(chuàng)建就能立即執(zhí)行。
3.提高線程的可管理性。可以根據系統的承受能力,調整線程池中工作線線程的數目,防止因為消耗過多的內存,而把服務器累趴下(每個線程需要大約1MB內存,線程開的越多,消耗的內存也就越大,最后死機)。
練習三:Lambda表達式
- 問題:
- 請列舉Lambda語法的省略規(guī)則
- 答:
- 在Lambda標準格式的基礎上,使用省略寫法的規(guī)則為:
1.小括號內參數的類型可以省略;
2.如果小括號內有且僅有一個參,則小括號可以省略;
3.如果大括號內有且僅有一個語句,則無論是否有返回值,都可以省略大括號、return關鍵字及語句分號。
- 在Lambda標準格式的基礎上,使用省略寫法的規(guī)則為:
練習四:Lambda表達式
- 問題:
- 請列舉Lambda表達式的3個組成部分,并解釋說明。
- 答:
- Lambda標準格式 Lambda省去面向對象的條條框框,格式由3個部分組成:一些參數,一個箭頭,一段代碼。
- Lambda表達式的標準格式為:格式說明:
1.小括號內的語法與傳統方法參數列表一致:無參數則留空;多個參數則用逗號分隔。
2.->是新引入的語法格式,代表指向動作。
3.大括號內的語法與傳統方法體要求基本一致。
練習五:Lambda表達式
-
問題:
- 請描述Lambda的使用前提
-
答:
- Lambda的語法非常簡潔,完全沒有面向對象復雜的束縛。但是使用時有幾個問題需要特別注意:
1. 使用Lambda必須具有接口,且要求接口中有且僅有一個抽象方法。無論是JDK內置的 Runnable 、 Comparator 接口還是自定義的接口,只有當接口中的抽象方法存在且唯一時,才可以使用Lambda。
2. 使用Lambda必須具有上下文推斷。也就是方法的參數或局部變量類型必須為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();
}
}
- 請在指定位置插入代碼實現打印輸出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() {
//插入代碼處
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()方法,參數列表為空,不帶參數。
- 在編譯時期就會報錯
練習八:線程池練習
- 問題:
- 使用線程池創(chuàng)建多線程。模擬同學找老師學習Java。
1.創(chuàng)建線程池對象,包含2個線程。從線程池中獲取線程對象,然后調用MyRunnable中的run()。
2.在MyRunnable實現類中,首先在控制臺打印需求,“我需要一個老師”。模擬需要2秒鐘時間老師可以過來指導學生,并在控制臺打印老師的姓名。最后,在控制臺打印“教我java,教完后,老師回到了辦公室”;
- 使用線程池創(chuàng)建多線程。模擬同學找老師學習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) {
// 創(chuàng)建線程池對象
ExecutorService service = Executors.newFixedThreadPool(2);//包含2個線程對象
// 創(chuàng)建Runnable實例對象
MyRunnable r = new MyRunnable();
//自己創(chuàng)建線程對象的方式
// 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();
}
}
-
答:
- 使用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 方法,完成130和120的相減計算:
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);
}
}
- 給定一個計算器 Calculator 接口,內含抽象方法 calc (減法),其功能是可以將兩個數字進行相減,并返回差值。使用Lambda表達式在Test中完成調用。
- 答:
- 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);
}
}