Java线程池的使用

一、设置线程池的大小

考虑因素

1、计算密集型(可考虑设置线程池大小为:cpuNum+1)、IO密集型

2、任务等待时间、任务计算时间两者的比值

3、其它:内存、文件句柄、套接字句柄、数据库连接等

线程池大小 = cpuNum*目标cpu使用率*(1+任务等待时间/任务计算时间)

0<=目标cpu使用率<=1

获得CPU个数:int cupNum = Runtime.getRuntime().availableProcessors();

二、线程池的原理

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

1、corePoolSize:基本大小、目标大小(没有任务执行时,线程池的大小)

  • 只有工作队列满了才会创建超过corePoolSize数量的线程;
  • ThreadPoolExecutor创建初期,线程不会立即启动,等到有任务创建时才会启动,除非调用prestartAllCoreThreads方法。
  • allowCoreThreadTimeOut方法:通过这个方法使线程池中所有线程超时;应用:大小有限的线程池,希望在线程池在没有任务的情况下消灭所有线程,可启用该特性,并将corePoolSize设为零。

2、maximumPoolSize:最大大小;可同时活动的线程数量上限

3、keepAliveTime:存活时间,如果线程的空闲时间超过了存活时间,将会标记为可回收。(控制的是maximumPoolSize-corePoolSize部分的线程)


4、unit:单位

5、workQueue:工作队列

  • FIFO无界队列:LinkedBlockingQueue
  • FIFO有界队列:ArrayBlockingQueue
  • SynchronousQueue:
  • 1、要想把任务放入队列中,必须有另一个线程正在等待接收这个元素。否则创建新线程或执行饱和策略。
    2、任务会直接移交给执行它的线程,而不是放入队列中
    3、所以只有线程池是无界或可拒绝时SynchronousQueue才有实际价值
  • PriorityBlockingQueue:可根据优先级安排任务 

6、threadFactory:线程工厂

7、handler:饱和策略

  • 终止:AbortPolicy(默认):抛异常RejectedExecutionException
  • 抛弃:discard:抛弃下一个将被执行的任务,然后尝试重新提交新任务
  • 抛弃旧的:DiscardOldest抛弃下一个将被执行的任务,然后尝试重新提交新任务。
  • 调用者运行:caller-runs:下一个任务会在调用execute时在主线程中执行。在这个过程中,新来的任务会保存在TCP层的队列中。如果继续有任务过来,TCP层队列满了仍然会抛出异常。

8、扩展

  • beforeExecute
  • afterExecute
  • terminated:线程池完成关闭操作时调用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值