91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java線程池的使用方法有哪些

發布時間:2023-03-24 14:29:33 來源:億速云 閱讀:119 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“Java線程池的使用方法有哪些”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Java線程池的使用方法有哪些”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

    線程池的創建?法總共有 7 種,但總體來說可分為 2 類: 

    1. 通過 ThreadPoolExecutor 創建的線程池;        

    2. 通過 Executors 創建的線程池。

    線程池的創建?式總共包含以下 7 種(其中 6 種是通過 Executors 創建的, 1 種是通過 ThreadPoolExecutor 創建的):

    1. Executors.newFixedThreadPool:創建?個固定??的線程池,可控制并發的線程數,超出的線程會在隊列中等待;         
    2. Executors.newCachedThreadPool:創建?個可緩存的線程池,若線程數超過處理所需,緩存?段時間后會回收,若線程數不夠,則新建線程;        
     3. Executors.newSingleThreadExecutor:創建單個線程數的線程池,它可以保證先進先出的執?順序;         
    4. Executors.newScheduledThreadPool:創建?個可以執?延遲任務的線程池;         
    5. Executors.newSingleThreadScheduledExecutor:創建?個單線程的可以執?延遲任務的線程池;
    6. Executors.newWorkStealingPool:創建?個搶占式執?的線程池(任務執?順序不確定)【JDK1.8 添加】。
     7. ThreadPoolExecutor:最原始的創建線程池的?式,它包含了 7 個參數可供設置,后?會詳細講。

     1. 固定數量的線程池

    public class ThreadPoolDemo3 {
        public static void main(String[] args) {
            ExecutorService threadPool = Executors.newFixedThreadPool(2);
            //添加任務方式 1
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
     
            //添加任務方式2
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }
    }
    輸出:
    pool-1-thread-1
    pool-1-thread-2

    a.  線程池返回結果

    public class ThreadPoolDemo4 {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            ExecutorService threadPool =  Executors.newFixedThreadPool(2);
            //執行任務
            Future<Integer> result = threadPool.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    int num = new Random().nextInt(10);
                    System.out.println("隨機數" + num);
                    return num;
                }
            });
     
            //打印線程池返回方式
            System.out.println("返回結果:" + result.get());
        }
    }
    輸出
    隨機數8
    返回結果:8

    使用submit可以執行有返回值的任務或者是無返回值的任務;而execute只能執行不帶返回值的任務。 

    Java線程池的使用方法有哪些

    b. ?定義線程池名稱或優先級

    public class ThreadPoolDemo5 {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
             // 創建線程工廠
            ThreadFactory threadFactory = new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    //!!!!!!!一定要注意:要把任務Runnable設置給新創建的線程
                    Thread thread = new Thread(r);
                    //設置線程的命名規則
                    thread.setName("我的線程" + r.hashCode());
                    //設置線程的優先級
                    thread.setPriority(Thread.MAX_PRIORITY);
                    return thread;
                }
            };
            ExecutorService threadPool = Executors.newFixedThreadPool(2,threadFactory);
            //執行任務1
            Future<Integer> result = threadPool.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    int num = new Random().nextInt(10);
                    System.out.println(Thread.currentThread().getPriority() + ", 隨機數:" + num);
                    return num;
                }
            });
            //打印線程池返回結果
            System.out.println("返回結果:" + result.get());
        }
    }

     提供的功能:

            1. 設置(線程池中)線程的命名規則。

            2. 設置線程的優先級。

            3. 設置線程分組。

            4. 設置線程類型(用戶線程、守護線程)。

    2. 帶緩存的線程池

    public class ThreadPoolDemo6 {
        public static void main(String[] args) {
            //創建線程池
            ExecutorService service = Executors.newCachedThreadPool();
            for (int i = 0; i < 10; i++) {
                int finalI = i;
                service.submit(() -> {
                    System.out.println("i : " + finalI + "|線程名稱:" + Thread.currentThread().getName());
                });
            }
        }
    }
    輸出
    i : 1|線程名稱:pool-1-thread-2
    i : 4|線程名稱:pool-1-thread-5
    i : 3|線程名稱:pool-1-thread-4
    i : 5|線程名稱:pool-1-thread-6
    i : 0|線程名稱:pool-1-thread-1
    i : 2|線程名稱:pool-1-thread-3
    i : 6|線程名稱:pool-1-thread-7
    i : 7|線程名稱:pool-1-thread-8
    i : 8|線程名稱:pool-1-thread-9
    i : 9|線程名稱:pool-1-thread-1

    優點:線程池會根據任務數量創建線程池,并且在一定時間內可以重復使用這些線程,產生相應的線程池。

    缺點:適用于短時間有大量任務的場景,它的缺點是可能會占用很多的資源。

    3. 執?定時任務 a. 延遲執?(?次)

    public class ThreadPoolDemo7 {
        public static void main(String[] args) {
            //創建線程池
            ScheduledExecutorService service = Executors.newScheduledThreadPool(5);
            System.out.println("添加任務的時間:" + LocalDateTime.now());
            //執行定時任務(延遲3s執行)只執行一次
            service.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println("執行子任務:" + LocalDateTime.now());
                }
            },3, TimeUnit.SECONDS);
        }
    }
    輸出
    添加任務的時間:2022-04-13T14:19:39.983
    執行子任務:2022-04-13T14:19:42.987

    Java線程池的使用方法有哪些

      b. 固定頻率執?

    public class ThreadPoolDemo8 {
        public static void main(String[] args) {
            //創建線程池
            ScheduledExecutorService service = Executors.newScheduledThreadPool(5);
            System.out.println("添加任務時間:" + LocalDateTime.now());
            //2s之后開始執行定時任務,定時任務每隔4s執行一次
            service.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    System.out.println("執行任務:" + LocalDateTime.now());
                }
            },2,4, TimeUnit.SECONDS);
        }
    }
    輸出
    添加任務時間:2022-04-13T14:24:38.810
    執行任務:2022-04-13T14:24:40.814
    執行任務:2022-04-13T14:24:44.814
    執行任務:2022-04-13T14:24:48.813
    執行任務:2022-04-13T14:24:52.815
    執行任務:2022-04-13T14:24:56.813
    執行任務:2022-04-13T14:25:00.813
    執行任務:2022-04-13T14:25:04.814
    執行任務:2022-04-13T14:25:08.813
    ... ...
    ... ...
    執行任務:2022-04-13T14:26:44.814
    執行任務:2022-04-13T14:26:48.813

    Java線程池的使用方法有哪些

     注意事項:

    public class ThreadPoolDemo9 {
        public static void main(String[] args) {
            //創建線程池
            ScheduledExecutorService service = Executors.newScheduledThreadPool(5);
            System.out.println("添加任務時間:" + LocalDateTime.now());
            service.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    System.out.println("執行任務: " + LocalDateTime.now());
                    try {
                        Thread.sleep(5 * 1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },2,4, TimeUnit.SECONDS);
        }
    }
    輸出
    添加任務時間:2022-04-13T14:33:34.551
    執行任務: 2022-04-13T14:33:36.556
    執行任務: 2022-04-13T14:33:41.557
    執行任務: 2022-04-13T14:33:46.559
    執行任務: 2022-04-13T14:33:51.561
    執行任務: 2022-04-13T14:33:56.562
    執行任務: 2022-04-13T14:34:01.564
    執行任務: 2022-04-13T14:34:06.566
    執行任務: 2022-04-13T14:34:11.566
    執行任務: 2022-04-13T14:34:16.567
    執行任務: 2022-04-13T14:34:21.570
    執行任務: 2022-04-13T14:34:26.570
    ... ....

    Java線程池的使用方法有哪些

    c. scheduleAtFixedRate VS scheduleWithFixedDelay

    scheduleAtFixedRate 是以上?次任務的開始時間,作為下次定時任務的參考時間的(參考時間+延遲任務=任務執?)。 scheduleWithFixedDelay 是以上?次任務的結束時間,作為下次定時任務的參考時間的。

    public class ThreadPoolDemo10 {
        public static void main(String[] args) {
            //創建線程池
            ScheduledExecutorService service = Executors.newScheduledThreadPool(5);
            System.out.println("添加任務時間:" + LocalDateTime.now());
            //2s之后開始執行定時任務,定時任務每隔4s執行一次
            service.scheduleWithFixedDelay(new Runnable() {
                @Override
                public void run() {
                    System.out.println("執行任務:" + LocalDateTime.now());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, 2, 4, TimeUnit.SECONDS);
        }
    }
    輸出
    添加任務時間:2022-04-13T14:46:02.871
    執行任務:2022-04-13T14:46:04.876
    執行任務:2022-04-13T14:46:09.878
    執行任務:2022-04-13T14:46:14.880
    執行任務:2022-04-13T14:46:19.883
    執行任務:2022-04-13T14:46:24.885
    執行任務:2022-04-13T14:46:29.888
    執行任務:2022-04-13T14:46:34.888
    執行任務:2022-04-13T14:46:39.891
    執行任務:2022-04-13T14:46:44.893
    執行任務:2022-04-13T14:46:49.895
    執行任務:2022-04-13T14:46:54.897
    執行任務:2022-04-13T14:46:59.900
    執行任務:2022-04-13T14:47:04.901
    ... ...

    Java線程池的使用方法有哪些

    4. 定時任務單線程

    public class ThreadPoolDemo11 {
        public static void main(String[] args) {
            ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
            System.out.println("添加任務的時間:" + LocalDateTime.now());
            service.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println("執行時間:" + LocalDateTime.now());
                }
            },2, TimeUnit.SECONDS );
        }
    }
    輸出
    添加任務的時間:2022-04-13T15:06:38.100
    執行時間:2022-04-13T15:06:40.106

    5. 單線程線程池

    public class ThreadPoolDemo12 {
        public static void main(String[] args) {
            ExecutorService service = Executors.newSingleThreadScheduledExecutor();
            for (int i = 0; i < 10; i++) {
                service.submit(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("線程名:" + Thread.currentThread().getName());
                    }
                });
            }
        }
    }
    輸出
    線程名:pool-1-thread-1
    線程名:pool-1-thread-1
    線程名:pool-1-thread-1
    線程名:pool-1-thread-1
    線程名:pool-1-thread-1
    線程名:pool-1-thread-1
    線程名:pool-1-thread-1
    線程名:pool-1-thread-1
    線程名:pool-1-thread-1
    線程名:pool-1-thread-1

    (MS) 為什么不直接用線程?

    單線程的線程池又什么意義?

            1. 復用線程。

            2. 單線程的線程池提供了任務隊列和拒絕策略(當任務隊列滿了之后(Integer.MAX_VALUE),新來的任務就會拒絕策略)

    6. 根據當前CPU?成線程池

    public class ThreadPoolDemo13 {
        public static void main(String[] args) {
            ExecutorService service = Executors.newWorkStealingPool();
            for (int i = 0; i < 10; i++) {
                service.submit(() -> {
                    System.out.println("線程名" + Thread.currentThread().getName());
                });
                
                while(!service.isTerminated()) {
                }
            }
        }
    }
    輸出
    線程名ForkJoinPool-1-worker-1

    7. ThreadPoolExecutor

    (1). Executors ?動創建線程池可能存在的問題

    Java線程池的使用方法有哪些

    a. OOM 代碼演示
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
     
    public class ThreadPoolDemo54 {
        static class MyOOMClass {
            // 1M 空間(M KB Byte)
            private byte[] bytes = new byte[1 * 1024 * 1024];
       }
        public static void main(String[] args) throws InterruptedException {
            Thread.sleep(15 * 1000);
            ExecutorService service = Executors.newCachedThreadPool();
            Object[] objects = new Object[15];
            for (int i = 0; i < 15; i++) {
                final int finalI = i;
                service.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(finalI * 200);
                       } catch (InterruptedException e) {
                            e.printStackTrace();
                       }
                        MyOOMClass myOOMClass = new MyOOMClass();
                        objects[finalI] = myOOMClass;
                        System.out.println("任務:" + finalI);
                   }
               });
           }
       }
    }

    Java線程池的使用方法有哪些

    Java線程池的使用方法有哪些

     執行結果:

    Java線程池的使用方法有哪些

    b. 關于參數設置

    -XX:標準設置,所有 HotSpot 都?持的參數。 -X:?標準設置,特定的 HotSpot 才?持的參數。 -D:程序參數設置,-D參數=value,程序中使?:System.getProperty("獲取")。

    mx 是 memory max 的簡稱 

    (2).  ThreadPoolExecutor 使?

    a. ThreadPoolExecutor 參數說明

    Java線程池的使用方法有哪些

    b. 線程池執?流程

    Java線程池的使用方法有哪些

    c. 執?流程驗證

     <MS>

    線程池的重要執行節點:

    1. 當任務來了之后,判斷線程池中實際線程數是否小于核心線程數,如果小于就直接創建并執行任務。

    2. 當實際線程數大于核心線程數(正式員工),他就會判斷任務隊列是否已滿,如果未滿就將任務存放隊列即可。

    3. 判斷線程池的實際線程數是否大于最大線程數(正式員工 + 臨時員工),如果小于最大線程數,直接創建線程執行任務;實際線程數已經等于最大線程數,則會直接執行拒絕策略。

    d. 拒絕策略

    (4種 JDK 提供的拒絕策略 + 1 種 自定義拒絕策略)

    Java線程池的使用方法有哪些

    Java ?帶的拒絕策略,CallerRunsPolicy:

    public class ThreadPoolDemo14 {
        public static void main(String[] args) {
            ThreadFactory factory = new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    Thread thread = new Thread(r);
                    return thread;
                }
            };
            // 手動創建線程池
            ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 100, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1), new ThreadPoolExecutor.CallerRunsPolicy());
            for (int i = 0; i < 4; i++) {
                int finalI = i;
                executor.submit(() -> {
                    System.out.println(Thread.currentThread().getName() + "執行任務:" + finalI);
                });
            }
            //終止線程
            executor.shutdown();
        }
    }
    輸出
    main執行任務:2
    pool-1-thread-1執行任務:0
    main執行任務:3
    pool-1-thread-1執行任務:1

    ?定義拒絕策略:

    Java線程池的使用方法有哪些

    線程狀態

    Java線程池的使用方法有哪些

    shutdown 執?時線程池終?接收新任務,并且會將任務隊列中的任務處理完; shutdownNow 執?時線程池終?接收新任務,并且會給終?執?任務隊列中的任務。

    1. RUNNING:這個沒什么好說的,這是最正常的狀態:接受新的任務,處理等待隊列中的任務; SHUTDOWN:不接受新的任務提交,但是會繼續處理等待隊列中的任務; 2. STOP:不接受新的任務提交,不再處理等待隊列中的任務,中斷正在執?任務的線程;

    3. TIDYING:所有的任務都銷毀了,workCount 為 0。線程池的狀態在轉換為 TIDYING 狀態時,會執 ?鉤??法 terminated();

    4. TERMINATED:terminated() ?法結束后,線程池的狀態就會變成這個。

    讀到這里,這篇“Java線程池的使用方法有哪些”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    阿克苏市| 西充县| 长葛市| 娄烦县| 太和县| 临沂市| 桂阳县| 英山县| 大冶市| 蒙阴县| 穆棱市| 博客| 古蔺县| 响水县| 兴化市| 理塘县| 湖北省| 台北市| 云浮市| 景宁| 崇明县| 华阴市| 股票| 青冈县| 云梦县| 思南县| 喀什市| 鄂州市| 汨罗市| 衡水市| 闸北区| 新巴尔虎左旗| 彭山县| 神农架林区| 海淀区| 蓝田县| 乌苏市| 黄陵县| 淮滨县| 林西县| 白水县|