Java ThreadPoolExecutor的参数深入理解

2025-05-29 0 69

Java ThreadPoolExecutor参数深入理解

一、使用Executors创建线程池

之前创建线程的时候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()这三个方法。当然Executors也是用不同的参数去new ThreadPoolExecutor

1. newFixedThreadPool()

创建线程数固定大小的线程池。 由于使用了LinkedBlockingQueue所以maximumPoolSize 没用,当corePoolSize满了之后就加入到LinkedBlockingQueue队列中。每当某个线程执行完成之后就从LinkedBlockingQueue队列中取一个。所以这个是创建固定大小的线程池。

?

1

2

3

4

5

6

7

8

9

10

11

12

13
public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue<Runnable>());

}

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue<Runnable> workQueue) {

this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

Executors.defaultThreadFactory(), defaultHandler);

}

2.newSingleThreadPool()

创建线程数为1的线程池,由于使用了LinkedBlockingQueue所以maximumPoolSize 没用,corePoolSize为1表示线程数大小为1,满了就放入队列中,执行完了就从队列取一个。

?

1

2

3

4

5

6
public static ExecutorService newSingleThreadExecutor() {

return new FinalizableDelegatedExecutorService

(new ThreadPoolExecutor(1, 1,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue<Runnable>()));

}

3.newCachedThreadPool()

创建可缓冲的线程池。没有大小限制。由于corePoolSize为0所以任务会放入SynchronousQueue队列中,SynchronousQueue只能存放大小为1,所以会立刻新起线程,由于maxumumPoolSize为Integer.MAX_VALUE所以可以认为大小为2147483647。受内存大小限制。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14
public static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue<Runnable>());

}

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue<Runnable> workQueue) {

this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

Executors.defaultThreadFactory(), defaultHandler);

}

二、使用ThreadPoolExecutor创建线程池

ThreadPoolExecutor的构造函数

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21
public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue<Runnable> workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler) {

if (corePoolSize < 0 ||

maximumPoolSize <= 0 ||

maximumPoolSize < corePoolSize ||

keepAliveTime < 0)

throw new IllegalArgumentException();

if (workQueue == null || threadFactory == null || handler == null)

throw new NullPointerException();

this.corePoolSize = corePoolSize;

this.maximumPoolSize = maximumPoolSize;

this.workQueue = workQueue;

this.keepAliveTime = unit.toNanos(keepAliveTime);

this.threadFactory = threadFactory;

this.handler = handler;

}

参数

1、corePoolSize核心线程数大小,当线程数<corePoolSize ,会创建线程执行runnable

2、maximumPoolSize 最大线程数, 当线程数 >= corePoolSize的时候,会把runnable放入workQueue中

3、keepAliveTime 保持存活时间,当线程数大于corePoolSize的空闲线程能保持的最大时间。

4、unit 时间单位

5、workQueue 保存任务的阻塞队列

6、threadFactory 创建线程的工厂

7、handler 拒绝策略

任务执行顺序:

1、当线程数小于corePoolSize时,创建线程执行任务。

2、当线程数大于等于corePoolSize并且workQueue没有满时,放入workQueue中

3、线程数大于等于corePoolSize并且当workQueue满时,新任务新建线程运行,线程总数要小于maximumPoolSize

4、当线程总数等于maximumPoolSize并且workQueue满了的时候执行handler的rejectedExecution。也就是拒绝策略。

ThreadPoolExecutor默认有四个拒绝策略:

1、ThreadPoolExecutor.AbortPolicy() 直接抛出异常RejectedExecutionException

2、ThreadPoolExecutor.CallerRunsPolicy() 直接调用run方法并且阻塞执行

3、ThreadPoolExecutor.DiscardPolicy() 直接丢弃后来的任务

4、ThreadPoolExecutor.DiscardOldestPolicy() 丢弃在队列中队首的任务

当然可以自己继承RejectedExecutionHandler来写拒绝策略.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37
int corePoolSize = 1;

int maximumPoolSize = 2;

int keepAliveTime = 10;

// BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();

BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(5);

ThreadFactory threadFactory = Executors.defaultThreadFactory();

//线程池和队列满了之后的处理方式

//1.跑出异常

RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();

RejectedExecutionHandler handler2 = new ThreadPoolExecutor.CallerRunsPolicy();

RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardPolicy();

RejectedExecutionHandler handler4 = new ThreadPoolExecutor.DiscardOldestPolicy();

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, handler2);

for (int j = 1; j < 15; j++) {

threadPoolExecutor.execute(new Runnable() {

public void run() {

try {

System.out.println(Thread.currentThread().getName());

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

}

System.out.println(threadPoolExecutor);

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

原文链接:https://my.oschina.net/u/2250599/blog/498787

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java ThreadPoolExecutor的参数深入理解 https://www.kuaiidc.com/117762.html

相关文章

发表评论
暂无评论