java中線程池創建的幾種方式


java中創建線程池的方式一般有兩種:

Executors工廠方法創建

package com.javaBase.LineDistancePond;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 〈一句話功能簡述〉;
 * 〈功能詳細描述〉
 *
 * @author jxx
 * @see [相關類/方法](可選)
 * @since [產品/模塊版本] (可選)
 */
public class TestThreadPoolExecutor {

    public static void main(String[] args) {
        //創建使用單個線程的線程池
        ExecutorService es1 = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            es1.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "正在執行任務");
                }
            });
        }
        //創建使用固定線程數的線程池
        ExecutorService es2 = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            es2.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "正在執行任務");
                }
            });
        }
        //創建一個會根據需要創建新線程的線程池
        ExecutorService es3 = Executors.newCachedThreadPool();
        for (int i = 0; i < 20; i++) {
            es3.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "正在執行任務");
                }
            });
        }
        //創建擁有固定線程數量的定時線程任務的線程池
        ScheduledExecutorService es4 = Executors.newScheduledThreadPool(2);
        System.out.println("時間:" + System.currentTimeMillis());
        for (int i = 0; i < 5; i++) {
            es4.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println("時間:"+System.currentTimeMillis()+"--"+Thread.currentThread().getName() + "正在執行任務");
                }
            },3, TimeUnit.SECONDS);
        }
        //創建只有一個線程的定時線程任務的線程池
        ScheduledExecutorService es5 = Executors.newSingleThreadScheduledExecutor();
        System.out.println("時間:" + System.currentTimeMillis());
        for (int i = 0; i < 5; i++) {
            es5.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println("時間:"+System.currentTimeMillis()+"--"+Thread.currentThread().getName() + "正在執行任務");
                }
            },3, TimeUnit.SECONDS);
        }
    }
}

new ThreadPoolExecutor()自定義創建

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) ;

corePoolSize:核心池的大小,這個參數跟后面講述的線程池的實現原理有非常大的關系。在創建了線程池后,默認情況下,線程池中並沒有任何線程,而是等待有任務到來才創建線程去執行任務,除非調用了prestartAllCoreThreads()或者prestartCoreThread()方法,從這2個方法的名字就可以看出,是預創建線程的意思,即在沒有任務到來之前就創建corePoolSize個線程或者一個線程。默認情況下,在創建了線程池后,線程池中的線程數為0,當有任務來之后,就會創建一個線程去執行任務,當線程池中的線程數目達到corePoolSize后,就會把到達的任務放到緩存隊列當中;
maximumPoolSize:線程池最大線程數,這個參數也是一個非常重要的參數,它表示在線程池中最多能創建多少個線程;
keepAliveTime:表示線程沒有任務執行時最多保持多久時間會終止。默認情況下,只有當線程池中的線程數大於corePoolSize時,keepAliveTime才會起作用,直到線程池中的線程數不大於corePoolSize,即當線程池中的線程數大於corePoolSize時,如果一個線程空閑的時間達到keepAliveTime,則會終止,直到線程池中的線程數不超過corePoolSize。但是如果調用了allowCoreThreadTimeOut(boolean)方法,在線程池中的線程數不大於corePoolSize時,keepAliveTime參數也會起作用,直到線程池中的線程數為0;
unit:參數keepAliveTime的時間單位,有7種取值,在TimeUnit類中有7種靜態屬性:
TimeUnit.DAYS;               //
TimeUnit.HOURS;             //小時
TimeUnit.MINUTES;           //分鍾
TimeUnit.SECONDS;           //
TimeUnit.MILLISECONDS;      //毫秒
TimeUnit.MICROSECONDS;      //微妙
TimeUnit.NANOSECONDS;       //納秒

workQueue:一個阻塞隊列,用來存儲等待執行的任務,這個參數的選擇也很重要,會對線程池的運行過程產生重大影響,一般來說,這里的阻塞隊列有以下幾種選擇:

ArrayBlockingQueue
LinkedBlockingQueue
SynchronousQueue
PriorityBlockingQueue
ArrayBlockingQueue和PriorityBlockingQueue使用較少,一般使用LinkedBlockingQueue和SynchronousQueue。線程池的排隊策略與BlockingQueue有關。

threadFactory:用於設置創建線程的工廠,可以通過線程工廠給每個創建出來的線程做些更有意義的事情,比如設置daemon和優先級等等
handler:表示當拒絕處理任務時的策略,有以下四種取值:

1、AbortPolicy:直接拋出異常。
2、CallerRunsPolicy:只用調用者所在線程來運行任務。
3、DiscardOldestPolicy:丟棄隊列里最近的一個任務,並執行當前任務。
4、DiscardPolicy:不處理,丟棄掉。
5、也可以根據應用場景需要來實現RejectedExecutionHandler接口自定義策略。如記錄日志或持久化不能處理的任務。

ThreadPoolExecutor 源碼理解

 public static void test(int size) {
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 20, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<>(5));

        for (int i = 0; i < size; i++) {
            poolExecutor.execute(new DemoTask(i));


            Console.log("poolSize:" + poolExecutor.getPoolSize());
            Console.log("corePoolSize:" + poolExecutor.getCorePoolSize());
            Console.log("maximumPoolSize:" + poolExecutor.getMaximumPoolSize());
            Console.log("queue:" + poolExecutor.getQueue().size());
            Console.log("completedTaskCount:" + poolExecutor.getCompletedTaskCount());
            Console.log("largestPoolSize:" + poolExecutor.getLargestPoolSize());
            Console.log("keepAliveTime:" + poolExecutor.getKeepAliveTime(TimeUnit.SECONDS));

        }

        poolExecutor.shutdown();
    }

class DemoTask implements Runnable {

    private int taskNum;

    public DemoTask(int taskNum) {
        this.taskNum = taskNum;
    }

    @Override
    public void run() {
        Console.log(StringUtils.center("正在執行" + taskNum, 20, "="));

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Console.log(StringUtils.center("執行完畢" + taskNum, 20, "="));
    }
}

 

執行結果:

=======正在執行0========
poolSize:1
corePoolSize:5
maximumPoolSize:20
queue:0
completedTaskCount:0
largestPoolSize:1
keepAliveTime:2
poolSize:2
corePoolSize:5
maximumPoolSize:20
queue:0
completedTaskCount:0
=======正在執行1========
largestPoolSize:2
keepAliveTime:2
poolSize:3
corePoolSize:5
maximumPoolSize:20
=======正在執行2========
queue:0
completedTaskCount:0
largestPoolSize:3
keepAliveTime:2
poolSize:4
corePoolSize:5
maximumPoolSize:20
queue:0
=======正在執行3========
completedTaskCount:0
largestPoolSize:4
keepAliveTime:2
poolSize:5
corePoolSize:5
=======正在執行4========
maximumPoolSize:20
queue:0
completedTaskCount:0
largestPoolSize:5
keepAliveTime:2
poolSize:5
corePoolSize:5
maximumPoolSize:20
queue:1
completedTaskCount:0
largestPoolSize:5
keepAliveTime:2
poolSize:5
corePoolSize:5
maximumPoolSize:20
queue:2
completedTaskCount:0
largestPoolSize:5
keepAliveTime:2
poolSize:5
corePoolSize:5
maximumPoolSize:20
queue:3
completedTaskCount:0
largestPoolSize:5
keepAliveTime:2
poolSize:5
corePoolSize:5
maximumPoolSize:20
queue:4
completedTaskCount:0
largestPoolSize:5
keepAliveTime:2
poolSize:5
corePoolSize:5
maximumPoolSize:20
queue:5
completedTaskCount:0
largestPoolSize:5
keepAliveTime:2
poolSize:6
corePoolSize:5
maximumPoolSize:20
queue:5
completedTaskCount:0
largestPoolSize:6
keepAliveTime:2
poolSize:7
corePoolSize:5
maximumPoolSize:20
queue:5
completedTaskCount:0
largestPoolSize:7
keepAliveTime:2
=======正在執行11=======
poolSize:8
corePoolSize:5
maximumPoolSize:20
queue:5
completedTaskCount:0
=======正在執行12=======
=======正在執行10=======
largestPoolSize:8
keepAliveTime:2
poolSize:9
corePoolSize:5
=======正在執行13=======
maximumPoolSize:20
queue:5
completedTaskCount:0
largestPoolSize:9
keepAliveTime:2
poolSize:10
corePoolSize:5
maximumPoolSize:20
=======正在執行14=======
queue:5
completedTaskCount:0
largestPoolSize:10
keepAliveTime:2
poolSize:11
corePoolSize:5
maximumPoolSize:20
queue:5
=======正在執行15=======
completedTaskCount:0
largestPoolSize:11
keepAliveTime:2
poolSize:12
corePoolSize:5
maximumPoolSize:20
queue:5
completedTaskCount:0
=======正在執行16=======
largestPoolSize:12
keepAliveTime:2
poolSize:13
corePoolSize:5
maximumPoolSize:20
=======正在執行17=======
queue:5
completedTaskCount:0
largestPoolSize:13
keepAliveTime:2
poolSize:14
corePoolSize:5
maximumPoolSize:20
queue:5
=======正在執行18=======
completedTaskCount:0
largestPoolSize:14
keepAliveTime:2
poolSize:15
corePoolSize:5
maximumPoolSize:20
=======正在執行19=======
queue:5
completedTaskCount:0
largestPoolSize:15
keepAliveTime:2
=======執行完畢0========
=======正在執行5========
=======執行完畢1========
=======執行完畢2========
=======正在執行6========
=======正在執行7========
=======執行完畢4========
=======正在執行8========
=======執行完畢3========
=======正在執行9========
=======執行完畢13=======
=======執行完畢12=======
=======執行完畢10=======
=======執行完畢11=======
=======執行完畢15=======
=======執行完畢16=======
=======執行完畢14=======
=======執行完畢19=======
=======執行完畢18=======
=======執行完畢17=======
=======執行完畢5========
=======執行完畢7========
=======執行完畢6========
=======執行完畢8========
=======執行完畢9========

 

 

參考鏈接:Java線程池(一)

       Java線程池(二)


免責聲明!

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



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