Java線程池 與Lambda


七、線程池、Lambda

1.1基本概念:

​ 線程池:其實就是一個容納多個線程的容器,其中的線程可以反復使用,省去了頻繁創建線程對象的操作,無需反復創建線程而消耗過多的資源。

1.2線程池的好處:

​ 1.降低資源消耗。減少了創建和銷毀線程得我次數,每個工作線程都可以被重復利用,可執行多個任務。

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

​ 3.提高線程的可管理學。可以根據系統的承受能力,調用線程池中工作線程的數目,防止因為消耗過多的內存,而把服務器累趴下。

1.3線程池的使用:

​ Java中的線程池的頂級接口是java.util.concurrent.Executor,但是嚴格意義上講Executor並不是一個線程池,而只是一個執行線程的工具。真正的線程池接口是 java.util.concurrent.ExecutorService,要配置一個線程池是比較復雜的,尤其是對於線程池的原理不是很清楚的情況下,很有可能配置的線程池不是較優的,因此在Java.util.concurrent.Executors線程工廠類里面提供了一些靜態工廠,生成一些常用的線程池。官方建議使用Executors工程類創建線程池對象。

​ ExecutorExecutors類中有個創建線程池的方法如下:

​ public static ExecutorService newFixedThreadPool(int nThreads): 返回線程池對象。(創建的有界線程池,也就是池中的線程個數可以指定最大數量)

​ 獲得到一個線程池對象,那么怎么使用呢,在這里定義了一個使用線程池對象的方法如下:

​ *public Futrue<?> submit (Runnable task): 獲取線程池中的某一個線程對象,並執行

​ Future 接口:用來記錄線程任務執行完畢后產生的結果。線程池創建與使用

使用線程池線程對象的步驟:

​ 1.創建線程池對象。

​ 2.創建Runnable接口子類對象。(task)

​ 3.提交Runnable接口子類對象。(take task)

​ 4.關閉線程池(一般不做)

​ Runnable實現類代碼:

 
 
 
 
 
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("教我游泳,交完后,教練回到了游泳池");
    }
}
 

測試類:

 
 
 
 
 
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

借助Java8的全新語法,顯示用Lambda展示簡潔的實現Runnable開啟多線程

 
 
 
 
 
public class Demo02LambdaRunnable{
  public static void main(String[] args){
     new Thread (() -> System.out.println("子線程開啟!")).start()
    }
}
 
 
 
 
 
 
public class Demo04ThreadNameless {
    public static void main(String[] args) {
     new Thread(new Runnable() {
      @Override
      public void run() {
       System.out.println("多線程任務執行!");
      }
     }).start();
    }
}
 

8.1語義分析

仔細分析該代碼中的語義,Runnable接口只有一個run方法的定義:

  • public abstract void run();

即制定了一種做事情的方案(其實就是一個函數):

  • 無參數:不需要任何條件即可執行該方案。

  • 無返回值:該方案不產生任何結果。

  • 代碼塊(方法體):該方案的具體執行步驟。

    ​其中核心代碼:() -> System.out.println("子線程開啟!")

    ​ 我們先來分析一下匿名內部類的好處與弊端:

    ​ 一方面,匿名內部類可以幫助我們省去實現類的定義;

    ​ 另一方面,匿名內部類的語法--確實太復雜

8.2Lambda表達式介紹:

 
 
 
 
 
() -> System.out.println("多線程任務執行了!")
 

​ ~其中() 就是run方法的參數(無),代表不需要任何條件:

​ ~中間的一個箭頭代表將前面的參數傳遞給后面的代碼:

​ ~后面的輸出語句即業務邏輯代碼。

 

8.3標准格式:

​ 一些參數

​ 一個箭頭

​ 一段代碼

​ (參數類型 參數名稱) ->{代碼語句}

8.4格式說明:

​ ~小括號內的語法與傳統方法參數列表一致:無參數則留空;多個參數則用逗號分割

​ ~ -> 是新引入的語法格式,代表指向動作

​ ~大括號內的語法與傳統方法要求基本一致

8.5 Lambda的使用前提

​ Lambda的語法非常簡潔,完全沒有面向對象復雜的束縛,但是在使用時有幾個問題需要特別注意:

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

​ 2.使用Lambda必須具有上下文推斷。也就是方法參數或局部變量類型必須為Lambda對應的接口類型,才能使用Lambda作為該接口的實例

​ tips:有且僅有一個抽象方法的接口,稱為 函數式接口

 

問題1:
    請描述什么是線程池。

    答:  
       線程池:其實就是一個容納多個線程的容器,其中的線程可以反復使用,
       省去了頻繁創建線程對象的操作,無需反復創建線程而消耗過多資源。
       

問題2:
    請描述合理利用線程池能夠帶來的三個好處。

    答:
      1. 降低資源消耗。減少了創建和銷毀線程的次數,每個工作線程都可以被重復利用,可執行多個任務。
      2. 提高響應速度。當任務到達時,任務可以不需要的等到線程創建就能立即執行。
      3. 提高線程的可管理性。可以根據系統的承受能力,調整線程池中工作線線程的數目,防止因為消耗過多的內存,
         而把服務器累趴下(每個線程需要大約1MB內存,線程開的越多,消耗的內存也就越大,最后死機)。

問題3:
   請列舉Lambda語法的省略規則

    答:
        在Lambda標准格式的基礎上,使用省略寫法的規則為:
        1. 小括號內參數的類型可以省略;
        2. 如果小括號內有且僅有一個參,則小括號可以省略;
        3. 如果大括號內有且僅有一個語句,則無論是否有返回值,都可以省略大括號、return關鍵字及語句分號。

        
問題4:
   請列舉Lambda表達式的3個組成部分,並解釋說明。

    答:
    Lambda標准格式 Lambda省去面向對象的條條框框,格式由3個部分組成:一些參數,一個箭頭,一段代碼。
    Lambda表達式的標准格式為:格式說明:
    1. 小括號內的語法與傳統方法參數列表一致:無參數則留空;多個參數則用逗號分隔。
    2. ->是新引入的語法格式,代表指向動作。
    3. 大括號內的語法與傳統方法體要求基本一致。

問題5:
   請描述Lambda的使用前提
    
    答:
        Lambda的語法非常簡潔,完全沒有面向對象復雜的束縛。但是使用時有幾個問題需要特別注意:
            1. 使用Lambda必須具有接口,且要求接口中有且僅有一個抽象方法。無論是JDK內置的 Runnable 、 Comparator 接口還是自定義的接口,只有當接口中的抽象方法存在且唯一時,才可以使用Lambda。
            2. 使用Lambda必須具有上下文推斷。也就是方法的參數或局部變量類型必須為Lambda對應的接口類型,才能使用Lambda作為該接口的實例。

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM