Java【線程池、Lambda表達式】

見pdf

等待喚醒機制

wait和notify

第二章 線程池

如果併發的線程數量很多,並且每個線程都是執行一個時間很短的任務就結束了,這樣頻繁創建線程就會大大降低 系統的效率,因爲頻繁創建線程和銷燬線程需要時間。
容器->集合

java.util.concurrent.Executor 

線程池:JDK1.5之後提供的
   java.util.concurrent.Executors:線程池的工廠類,用來生成線程池
   Executors類中的靜態方法:
       static ExecutorService newFixedThreadPool(int nThreads) 創建一個可重用固定線程數的線程池
       參數:
           int nThreads:創建線程池中包含的線程數量
       返回值:
           ExecutorService接口,返回的是ExecutorService接口的實現類對象,我們可以使用ExecutorService接口接收(面向接口編程)
   java.util.concurrent.ExecutorService:線程池接口
       用來從線程池中獲取線程,調用start方法,執行線程任務
           submit(Runnable task) 提交一個 Runnable 任務用於執行
       關閉/銷燬線程池的方法
           void shutdown()
   線程池的使用步驟:
       1.使用線程池的工廠類Executors裏邊提供的靜態方法newFixedThreadPool生產一個指定線程數量的線程池
       2.創建一個類,實現Runnable接口,重寫run方法,設置線程任務
       3.調用ExecutorService中的方法submit,傳遞線程任務(實現類),開啓線程,執行run方法
       4.調用ExecutorService中的方法shutdown銷燬線程池(不建議執行)
 

public class Demo01ThreadPool {
    public static void main(String[] args) {
        //1.使用線程池的工廠類Executors裏邊提供的靜態方法newFixedThreadPool生產一個指定線程數量的線程池
        ExecutorService es = Executors.newFixedThreadPool(2);
        //3.調用ExecutorService中的方法submit,傳遞線程任務(實現類),開啓線程,執行run方法
        es.submit(new RunnableImpl());//pool-1-thread-1創建了一個新的線程執行
        //線程池會一直開啓,使用完了線程,會自動把線程歸還給線程池,線程可以繼續使用
        es.submit(new RunnableImpl());//pool-1-thread-1創建了一個新的線程執行
        es.submit(new RunnableImpl());//pool-1-thread-2創建了一個新的線程執行

        //4.調用ExecutorService中的方法shutdown銷燬線程池(不建議執行)
        es.shutdown();

        es.submit(new RunnableImpl());//拋異常,線程池都沒有了,就不能獲取線程了
    }

}

 

第三章 lamada表達式

1、Runnable

實現多線程程序

public class Demo01Runnable {
    public static void main(String[] args) {
        //創建Runnable接口的實現類對象
        RunnableImpl run = new RunnableImpl();
        //創建Thread類對象,構造方法中傳遞Runnable接口的實現類
        Thread t = new Thread(run);
        //調用start方法開啓新線程,執行run方法
        t.start();

        //簡化代碼,使用匿名內部類,實現多線程程序
        Runnable r = new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" 新線程創建了");
            }
        };
        new Thread(r).start();

        //簡化代碼
        new Thread(new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" 新線程創建了");
            }
        }).start();
    }
}

似乎只有方法體纔是關鍵

目的只有run方法

2、轉換編程思想

將 run 方法體內的代碼傳遞給 Thread 類知曉。
2014年3月Oracle所發佈的Java 8(JDK 1.8)中,加入了Lambda表達 式的重量級新特性,爲我們打開了新世界的大門。

函數式編程

留一個小括號()->一些代碼

new Thread(() ‐> System.out.println("多線程任務執行!")).start(); // 啓動線程

()接口中抽象方法的參數列表

3、

對匿名內部類的代替

package com.itheima.demo04.Lambda;
/*
    需求:
        給定一個廚子Cook接口,內含唯一的抽象方法makeFood,且無參數、無返回值。
        使用Lambda的標準格式調用invokeCook方法,打印輸出“喫飯啦!”字樣
 */
public class Demo01Cook {
    public static void main(String[] args) {
//        調用invokeCook方法,參數是Cook接口,傳遞Cook接口的匿名內部類對象
        invokeCook(new Cook() {
            @Override
            public void makeFood() {
                System.out.println("喫飯了");
            }
        });
//        使用Lambda表達式,簡化匿名內部類的書寫
        invokeCook(()->{
            System.out.println("喫飯了");
        });

        //優化省略Lambda
        invokeCook(()-> System.out.println("喫飯了"));
    }

    //定義一個方法,參數傳遞Cook接口,方法內部調用Cook接口中的方法makeFood
    public static void invokeCook(Cook cook){
        cook.makeFood();
    }
}

4、排序

 lamada表達式

方法有參數就寫參數,()->是實現類方法的體現

        Arrays.sort(arr,(Person o1, Person o2)->{
            return o1.getAge()-o2.getAge();
        });

        //優化省略Lambda
        Arrays.sort(arr,(o1, o2)->o1.getAge()-o2.getAge());

        //遍歷數組
        for (Person p : arr) {
            System.out.println(p);
        }

5、練習

invokeCalu(120,130,(int a,int b)->System.out.println("isheudi"));

是對匿名內部類的簡化的重要操作。

6、還可以省略

Lambda表達式:是可推導,可以省略
凡是根據上下文推導出來的內容,都可以省略書寫
可以省略的內容:
    1.(參數列表):括號中參數列表的數據類型,可以省略不寫
    2.(參數列表):括號中的參數如果只有一個,那麼類型和()都可以省略
    3.{一些代碼}:如果{}中的代碼只有一行,無論是否有返回值,都可以省略({},return,分號)
        注意:要省略{},return,分號必須一起省略

一個參數可以省略參數

new Thread(()->System.out.println(Thread.currentThread().getName()+" 新線程創建了")).start();

 

1. 使用Lambda必須具有接口,且要求接口中有且僅有一個抽象方法。

備註:有且僅有一個抽象方法的接口,稱爲“函數式接口”。
 

 

 

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