Java ThreadPoolExecutor的参数深入理解

网友投稿 213 2023-05-31


Java ThreadPoolExecutor的参数深入理解

java ThreadPoolExecutor的参数深入理解

一、使用Executors创建线程池

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

1. newFixedThreadPool()

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

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue());

}

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue) {

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

Executors.defaultThreadFactory(), defaultHandler);

}

2.newSingleThreadPool()

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

public static ExecutorService newSingleThreadExecutor() {

return new FinalizableDelegatedExecutorService

(new ThreadPoolExecutor(1, 1,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue()));

}

3.newCachedThreadPool()

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

public static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue());

}

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue) {

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

Executors.defaultThreadFactory(), defaultHandler);

}

二、使用ThreadPoolExecutor创建线程池

ThreadPoolExecutor的构造函数

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue 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核心线程数大小,当线程数

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

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

&http://nbsp;      4、unit 时间单位

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

6、threadFactory 创建线程的工厂

7、handler 拒绝策略

任务执行顺序:

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

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

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

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

ThreadPoolYcSWgonSbFExecutor默认有四个拒绝策略:

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

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

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

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

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

int corePoolSize = 1;

int maximumPoolSize = 2;

int keepAliveTime = 10;

// BlockingQueue workQueue = new LinkedBlockingQueue();

BlockingQueue workQueue = new ArrayBlockingQueue(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);

}

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

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

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

&http://nbsp;      4、unit 时间单位

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

6、threadFactory 创建线程的工厂

7、handler 拒绝策略

任务执行顺序:

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

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

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

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

ThreadPoolYcSWgonSbFExecutor默认有四个拒绝策略:

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

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

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

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

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

int corePoolSize = 1;

int maximumPoolSize = 2;

int keepAliveTime = 10;

// BlockingQueue workQueue = new LinkedBlockingQueue();

BlockingQueue workQueue = new ArrayBlockingQueue(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);

}

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java中参数传递方式详解
下一篇:java 中ThreadLocal本地线程和同步机制的比较
相关文章

 发表评论

暂时没有评论,来抢沙发吧~