线程池-创建

线程池:管理同一组同构工作线程的资源池

创建线程池

1、通过调用Executors中的静态工厂方法来创建线程池

Executors
newFixedThreadPool:固定长度的线程池
newCachedThreadPool:可缓存的线程池。如果线程池的当前规模超过了处理需求时,那么将回收空闲线程,而当需求增加时,则可以添加新的线程。线程池的规模不存在任何限制。
newSingleThreadExecutor :单线程的Executor,它创建单个工作者线程来执行任务,如果这个线程异常结束,会创建另一个线程来替代。newSingleThreadExecutor能确保依照任务在队列中的顺序来串行执行。
newScheduledThreadPool:创建了一个固定长度的线程池,而且以延迟或定时的方式来执行任务。

ExecutorService executorService = Executors.newFixedThreadPool(2);

在阿里巴巴java开发者手册中并不推荐使用Executors创建线程池:

【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

2、ThreadPoolExecutor

TreadPoolExecutor是一个灵活的、稳定的线程池,允许进行各种定制。
TreadPoolExecutor
TreadPoolExecutor一个通用构造函数:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }

xml配置:

<bean id="myTaskExecutor"
          class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="20"/>
        <property name="maxPoolSize" value="40"/>
        <property name="queueCapacity" value="40"/>
        <property name="keepAliveSeconds" value="30"/>
    </bean>

corePoolSize :线程池的基本大小,即在没有任务执行时线程池的大小,并且只有在工作队列满了的情况下才会创建超出基本大小的线程。
maxPoolSize:线程池的最大大小,即可同时活动的线程数量的上限。
如果某个线程的空闲时间超过的存活时间keepAliveSeconds,那么将被标记为可回收的,并且当线程池的当前大小超过了基本大小时,这个线程将被终止。

ThreadPoolExecutor允许提供一个BlockingQueue来保存等待执行的任务。基本的任务排队方法有3种:

  • 无界队列
  • 有界队列
  • 同步移交

无界队列无界的LinkedBlockingQueue,如果所有工作线程都处于忙碌状态,那么任务将在队列中等候。如果任务持续快速到达,并且超过了线程池处理他们的速度,那么队列将无限制地增加

有界队列是一种更为稳妥的管理策略,如ArrayBlockingQueue,有界的LinkedBlockingQueuePriorityBlockingQueue

同步移交使用SynchronousQueue来避免任务排队,以及直接将任务从生产者移交给工作者线程。SynchronousQueue不是一个真正的队列,而是一个线程之间进行移交的机制。将一个元素放入SynchronousQueue中,必须有另外一个线程正在等待接受这个元素。如果没有并且当前线程池的大小小于最大值,则创建一个新的线程,否则这个任务将被拒绝。

解读 Java 并发队列 BlockingQueue

扩展ThreadPoolExecutor

ThreadPoolExecutor是可扩展的,它提供了几个可以在子类改写的方法:beforeExecute、afterExecute、terminated

public class MyThreadPoolExecutor extends ThreadPoolExecutor{
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }
    
    @Override
    protected void beforeExecute(Thread t,Runnable r){
        
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) { 
        
    }

    @Override
    protected void terminated() { 
        
    }
    
}

beforeExecute、afterExecute方法可以添加日志、计时、监视或统计信息的功能。无论任务是从run中正常返回,还是抛出异常,afterExecute方法都会被调用(如果任务完成后带一个Error,那么就不会调用afterExecute)。
在线程池完成关闭操作时调用terminated,terminated可以用来释放分配的各种资源、执行发送通知、记录日志或者收集finalize统计信息等操作。

参考:
《java并发编程实战》
https://blog.csdn.net/qq_33300570/article/details/78394188

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值