欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java中線程池最實(shí)用的創(chuàng)建與關(guān)閉指南

 更新時(shí)間:2021年09月09日 10:47:39   作者:jacky 鄭  
試中經(jīng)常會(huì)問到,創(chuàng)建一個(gè)線程池需要哪些參數(shù)啊,線程池的工作原理啊,卻很少會(huì)問到線程池如何安全關(guān)閉的,下面這篇文章主要給大家介紹了關(guān)于java中線程池最實(shí)用的創(chuàng)建與關(guān)閉的相關(guān)資料,需要的朋友可以參考下

前言

在日常的開發(fā)工作當(dāng)中,線程池往往承載著一個(gè)應(yīng)用中最重要的業(yè)務(wù)邏輯,因此我們有必要更多地去關(guān)注線程池的執(zhí)行情況,包括異常的處理和分析等。

線程池創(chuàng)建

避免使用Executors創(chuàng)建線程池,主要是避免使用其中的默認(rèn)實(shí)現(xiàn),那么我們可以自己直接調(diào)用ThreadPoolExecutor的構(gòu)造函數(shù)來自己創(chuàng)建線程池。在創(chuàng)建的同時(shí),給BlockQueue指定容量就可以了。

private static ExecutorService executor = new ThreadPoolExecutor(10, 10,
        60L, TimeUnit.SECONDS,
        new ArrayBlockingQueue(10));

這種情況下,一旦提交的線程數(shù)超過當(dāng)前可用線程數(shù)時(shí),就會(huì)拋出java.util.concurrent.RejectedExecutionException,這是因?yàn)楫?dāng)前線程池使用的隊(duì)列是有邊界隊(duì)列,隊(duì)列已經(jīng)滿了便無法繼續(xù)處理新的請(qǐng)求。但是異常(Exception)總比發(fā)生錯(cuò)誤(Error)要好。

除了自己定義ThreadPoolExecutor外。還有其他方法。這個(gè)時(shí)候第一時(shí)間就應(yīng)該想到開源類庫,如apache和guava等。

推薦使用guava提供的ThreadFactoryBuilder來創(chuàng)建線程池。

public class ExecutorsDemo {
 
    private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
        .setNameFormat("demo-pool-%d").build();
 
    private static ExecutorService pool = new ThreadPoolExecutor(5, 200,
        0L, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
 
    public static void main(String[] args) {
 
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            pool.execute(new SubThread());
        }
    }
}


只需要執(zhí)行shutdown就可以優(yōu)雅關(guān)閉

package com.zxd.concurrent;

import com.google.common.collect.Lists;

import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {


    public static void main(String[] args) {
        // TODO 如何正確優(yōu)雅簡單的關(guān)閉線程池 ,無須其他多余操 ;創(chuàng)建線程池我選擇用這種方法比較可靠
        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        //接收處理數(shù)據(jù)的結(jié)果集合
        List<Integer> resList = Lists.newArrayList();
        //開啟的任務(wù) 我們?cè)O(shè)置的核心處理線程數(shù)5個(gè)所以 會(huì)有多出來的線程在隊(duì)列中等待
        for (int i = 0; i < 30; i++) {
            executor.execute(new Task(i, resList));
        }
        //1、關(guān)閉線程池 一定要在循環(huán)結(jié)束關(guān)閉
        //2、這個(gè)關(guān)閉方法不會(huì)立即關(guān)閉所有在執(zhí)行的任務(wù)線程,
        executor.shutdown();
        //4.這里是檢查線程池是否所有任務(wù)都執(zhí)行完畢關(guān)閉
        int j = 0;
        while (true) {
            //5.這里是等線程池徹底關(guān)閉以后做的判斷 保證所有線程池已經(jīng)全部關(guān)閉退出while循環(huán)
            if (executor.isTerminated()) {
                System.out.println("所有線程已經(jīng)運(yùn)行完畢:" + j);
                break;
            }
            // 為避免一直循環(huán) 加個(gè)睡眠
            try {
                //如果執(zhí)行shutdown方法沒有關(guān)閉的線程池線程池會(huì)嘗試關(guān)閉
                System.out.println("嘗試關(guān)閉線程次數(shù):" + j);
                j++;
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //FIXME 3、下面的方法會(huì)立即關(guān)閉線程池,沒有執(zhí)行完的也不會(huì)在執(zhí)行了,如果有等待隊(duì)列的任務(wù)也不會(huì)繼續(xù)執(zhí)行
        System.out.println("【完成的總線程數(shù)】:" + resList.size());

    }

    static class Task implements Runnable {
        int name;

        List<Integer> list;

        public Task(int name, List<Integer> list) {
            this.name = name;
            this.list = list;
        }

        @Override
        public void run() {
            for (int i = 1; i <= 10; i++) {
                int j = i * 10;
                // 做業(yè)務(wù)處理
                //System.out.println("task " + name + " is running");
            }
            list.add(name + 1);
            System.out.println("task " + name + " is over");
        }
    }

}

輸出結(jié)果

task 0 is over
task 3 is over
task 1 is over
task 2 is over
task 7 is over
task 6 is over
task 5 is over
嘗試關(guān)閉線程次數(shù):0
task 10 is over
task 9 is over
task 4 is over
task 8 is over
task 14 is over
task 13 is over
task 12 is over
task 11 is over
task 18 is over
task 17 is over
task 16 is over
task 15 is over
task 22 is over
task 21 is over
task 20 is over
task 19 is over
task 26 is over
task 25 is over
task 24 is over
task 23 is over
task 29 is over
task 28 is over
task 27 is over
所有線程已經(jīng)運(yùn)行完畢:1
【完成的總線程數(shù)】:30

執(zhí)行shutdownNow關(guān)閉的測試

package com.zxd.concurrent;

import com.google.common.collect.Lists;

import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {


    public static void main(String[] args) {
        // TODO 如何正確優(yōu)雅簡單的關(guān)閉線程池 ,無須其他多余操 ;創(chuàng)建線程池我選擇用這種方法比較可靠
        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        //接收處理數(shù)據(jù)的結(jié)果集合
        List<Integer> resList = Lists.newArrayList();
        //開啟的任務(wù) 我們?cè)O(shè)置的核心處理線程數(shù)5個(gè)所以 會(huì)有多出來的線程在隊(duì)列中等待
        for (int i = 0; i < 200; i++) {
            executor.execute(new Task(i, resList));
        }
        //1、關(guān)閉線程池 一定要在循環(huán)結(jié)束關(guān)閉
        //2、這個(gè)關(guān)閉方法不會(huì)立即關(guān)閉所有在執(zhí)行的任務(wù)線程,
//        executor.shutdown();
        //FIXME 3、下面的方法會(huì)立即關(guān)閉線程池,沒有執(zhí)行完的也不會(huì)在執(zhí)行了,如果有等待隊(duì)列的任務(wù)也不會(huì)繼續(xù)執(zhí)行
        List<Runnable> list = executor.shutdownNow();
        System.out.println("c剩余的沒有執(zhí)行的任務(wù)【線程數(shù)】= " + list.size());
        System.out.println("【完成的總線程數(shù)】:" + resList.size());
        //4.這里是檢查線程池是否所有任務(wù)都執(zhí)行完畢關(guān)閉
        int j = 0;
        while (true) {
            //5.這里是等線程池徹底關(guān)閉以后做的判斷 保證所有線程池已經(jīng)全部關(guān)閉退出while循環(huán)
            if (executor.isTerminated()) {
                System.out.println("所有線程已經(jīng)運(yùn)行完畢:" + j);
                break;
            }
            // 為避免一直循環(huán) 加個(gè)睡眠
            try {
                //如果執(zhí)行shutdown方法沒有關(guān)閉的線程池線程池會(huì)嘗試關(guān)閉
                System.out.println("嘗試關(guān)閉線程次數(shù):" + j);
                j++;
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    static class Task implements Runnable {
        int name;

        List<Integer> list;

        public Task(int name, List<Integer> list) {
            this.name = name;
            this.list = list;
        }

        @Override
        public void run() {
            for (int i = 1; i <= 10; i++) {
                int j = i * 10;
                // 做業(yè)務(wù)處理
                //System.out.println("task " + name + " is running");
            }
            list.add(name + 1);
            System.out.println("task " + name + " is over");
        }
    }

}

輸出結(jié)果

總結(jié)

到此這篇關(guān)于java中線程池最實(shí)用的創(chuàng)建與關(guān)閉的文章就介紹到這了,更多相關(guān)java線程池創(chuàng)建與關(guān)閉內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論