java io线程池_java线程池

线程池篇

建议使用ThreadPoolExecutor类进行线程池的创建,更加细粒度的管理自己所使用的线程池,对线程池的分配也根据自己的实际情况来具体的控制

如果使用线程池可能会导致OOM(outofMemoryError)

核数的获取

获取当前电脑的核数:Runtime.getRuntime().availableProcessors();

ThreadPoolExecutor

线程池最底层的类ThreadPoolExecutor

ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(

2,

/*

* IO 密集型 CPU*2

* CPU密集型 CPU核数+1 (逻辑处理器+1)

* */

5,

60L,

TimeUnit.SECONDS,

//默认是Integer.Max_Value

new LinkedBlockingQueue(3),

Executors.defaultThreadFactory(),

/**

* abort RejectedExecutionException

* CallerRunsPolicy 会回退到上一个线程,比如main线程

* DiscardPolicy 放心新来的

* DiscardOldestPolicy 放弃阻塞队列中最开始的那个

*/

new ThreadPoolExecutor.DiscardOldestPolicy());

de08d4da08af7533360e5a4995735201.png

Executors工具类

newWorkStealingPool(1.8)

public static ExecutorService newWorkStealingPool(int parallelism) {

return new ForkJoinPool

(parallelism,

ForkJoinPool.defaultForkJoinWorkerThreadFactory,

null, true);

}

public ForkJoinPool(int parallelism,

ForkJoinWorkerThreadFactory factory,

UncaughtExceptionHandler handler,

boolean asyncMode) {

this(checkParallelism(parallelism),

checkFactory(factory),

handler,

asyncMode ? FIFO_QUEUE : LIFO_QUEUE,

"ForkJoinPool-" + nextPoolId() + "-worker-");

checkPermission();

}

private ForkJoinPool(int parallelism,

ForkJoinWorkerThreadFactory factory,

UncaughtExceptionHandler handler,

int mode,

String workerNamePrefix) {

this.workerNamePrefix = workerNamePrefix;

this.factory = factory;

this.ueh = handler;

this.config = (parallelism & SMASK) | mode;

long np = (long)(-parallelism); // offset ctl counts

this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);

}

//分支合并线程池

newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue());

}

创建固定的线程数,创建的初始值和最大值都是一个

创建的阻塞队列无上限

newCachedThreadPool

public static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue());

}

带缓存的线程池数,当开始的时候是0,最大是Integer.MAX_VALUE

最长六十秒不被使用则被回收

newSingleThreadPool

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {

return new DelegatedScheduledExecutorService

(new ScheduledThreadPoolExecutor(1));

}

创建一个单个的线程池(里面只有一个)

newScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(

int corePoolSize, ThreadFactory threadFactory) {

return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);

}

public ScheduledThreadPoolExecutor(int corePoolSize,

ThreadFactory threadFactory) {

super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,

new DelayedWorkQueue(), threadFactory);

}

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory) {

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

threadFactory, defaultHandler);

}

创建一个带时间的线程池,使用的是DelayedWorkQueue拒绝阻塞队列

线程池的使用

execute():void

submit():Future

对无返回值的线程执行

try {

for (int i = 0; i < 9; i++) {

poolExecutor.execute(() -> {

System.out.println(Thread.currentThread().getName() + "\t");

});

}

} catch (Exception e) {

e.printStackTrace();

} finally {

poolExecutor.shutdown();

}

对有返回值的线程执行

poolExecutor.submit(new FutureTask<>(() -> 1024)).get();

线程池的执行流程

首先来的线程任务开始开启小于等于corePoolSize的线程进行执行

如果有些线程还是没执行完,但是有新的任务来了,那么将会进入阻塞队列

如果阻塞队列满了,就会去开启新的线程来执行任务,线程<=MaxiNumPoolSize

当大于corePoolSize的线程在KeepAliveTime内没被使用则会被释放

如果开启了最大的线程还是有任务没有被执行,则会进行使用拒绝策略进行对新任务的拒绝

e7e5911412d5940df877ee64a1ec6714.png

0686db7fd72999dd20556b4ab8f71fb5.png

线程池具体参数的配置*

线程池的拒绝策略

当等待队列满了&线程池的最大线程数也达到了,当出现新的任务时,会执行拒绝策略

new ThreadPoolExecutor.CallerRunsPolicy()

abortPolicy 抛出RejectedExecutionException,阻止系统正常运行

CallerRunsPolicy 会回退到上一个线程(调用它的线程),比如main线程

DiscardPolicy 放弃新来的task,如果允许任务丢失,则是最好的一种策略

DiscardOldestPolicy 放弃阻塞队列中最开始的那个

上述策略皆实现了RejectedExecutionHandler接口

线程池最大线程数的设定

CPU密集型

CPU核数+1个线程的线程池

IO密集型

IO密集型任务线程并不是一直在执行任务,则应尽可能多的线程,CUP核数*2

CUP核数 / 1-阻塞系数 (阻塞系数在0.8~0.9之间)

比如8核CPU: 4/1-0.9 = 40

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值