理解线程池

线程

进程、线程,经常傻傻分不清楚。
进程,是一个动态的过程,是一个活动的实体。简单来说,一个应用程序的运行就可以被看做是一个进程。
在这里插入图片描述
而线程,是运行中的实际的任务执行者,它是程序执行流的最小执行单位。
可以说,进程中包含了多个同时运行的线程。

关于进程和线程,可以查看阮一峰的这篇文章,浅显易懂。

线程的生命周期

new Thread()创建一个新线程,在线程创建完成后,线程就进入了就绪(Runnable)状态,并开始抢占CPU资源。
当线程抢到了CPU执行权,线程就进入了运行(Running)状态。
当线程的任务执行完成或者调用stop()后,线程就进入了死亡状态。

线程也可能进入阻塞状态,比如,

  • 当线程主动调用sleep()时,线程会进入阻塞状态。而当sleep()的睡眠时长过去之后,线程会自动跳出阻塞状态。
  • 当线程主动调用阻塞时的IO方法时,这个方法有个返回参数,在该参数返回之前,线程会进入阻塞状态。参数返回之后,线程会自动跳出阻塞状态。
  • 当线程正在等待某个通知时,会进入阻塞状态。当线程获取到了通知后,就会自动跳出阻塞过程。
生命周期函数
  • start()
  • run()
  • stop()
  • sleep()
  • wait()
单线程与多线程

单线程,只有一个线程在执行任务。
多线程,有多个线程同时在执行任务。

线程池的创建

Java提供了创建线程池的接口类Executor

public interface Executor {

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the {@code Executor} implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}

通常我们会实现Executor的实现类ThreadPoolExecutor来创建线程池。

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}
  • corePoolSize,线程池中的核心线程数量。
  • maximumPoolSize,线程池中可以容纳的最大线程数量。
  • keepAliveTime,非核心线程在空闲时间里最大的存活时间。线程池中的核心线程,即使在无任务的情况下也不能被清除,其他的线程则是有存活时间的。
  • workQueue,等待队列,任务可以存储在任务队列中等待被执行。
线程池的执行

在这里插入图片描述
当有任务进来时,判断核心线程是否处于空闲状态,如果不是空闲状态,则核心线程先执行任务;
如果核心线程已满,则判断任务队列是否有空间存放该任务,如果有,则将该任务保存在任务队列中,等待执行;
如果任务队列已满,则判断线程池最大可容纳的线程数,如果没有超出这个数,就创建非核心线程执行任务;
如果超出了这个数,则调用handler实现拒绝策略。

handler的拒绝策略有四种,分别是,

  • AbortPolicy。不执行新任务,直接抛出异常。
  • DiscardPolicy。不执行新任务,也不抛出异常。
  • DiscardOldestPolicy。抛弃线程池中最后要执行的任务,并执行新传进来的任务。
  • CallerRunsPolicy。直接调用execute来执行当前任务。
常见的线程池
  • CachedThreadPool
    可缓存的线程池,该线程池中没有核心线程,有非核心线程,非核心线程的数量为Integer.MAX_VALUE,即无限大。当有需要时,创建线程来执行任务;当没有需要时,则回收线程。使用于耗时少、任务量大的情况。
  • ScheduleThreadPool
    周期性执行任务的线程池。按照某种特定的计划执行线程中的任务,有核心线程,也有非核心线程,非核心线程的数量为无限大。适用于执行周期性任务的情况。
  • SingleThreadPool
    只有一条线程来执行任务,适用于有顺序的任务的应用场景。
  • FixedThreadPool
    定长的线程池,有核心线程,核心线程的数量为最大的线程数量,没有非核心线程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值