多线程--线程池

Posted Kirl z

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程--线程池相关的知识,希望对你有一定的参考价值。

多线程--线程池

1. 作用

不用每次执行任务时, 都创建线程(会真实穿件系统级别的线程, 比较耗时, 销毁也是), 而是可以使用线程池中的线程来复用

2. ThreadPoolExecutor

  • corePoolSize(线程池的基本大小):核心线程数
  • runnableTaskQueue(任务队列):阻塞队列。
    ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO(先进先出)原则对元素进行排序。
    LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO排序元素
    SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。
    PriorityBlockingQueue:一个具有优先级的无限阻塞队列。
  • maximumPoolSize(线程池最大数量):线程池允许创建的最大线程数。
  • keepAliveTime(线程活动保持时间):空闲时间数量,
    所以,如果任务很多,并且每个任务执行的时间比较短,可以调大时间,提高线程的利用率。
  • TimeUnit(线程活动保持时间的单位):空闲时间单位, 天(DAYS)、小时(HOURS)、分钟
    (MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)和纳秒
    (NANOSECONDS,千分之一微秒)。
  • RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,表示无法处理新任务时抛出异常。提供了以下4种策略。
    AbortPolicy:直接抛出异常拒绝执行。
    CallerRunsPolicy:提交者,执行。
    DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
    DiscardPolicy:不处理,丢弃掉时间最久的。
        ExecutorService pool = new ThreadPoolExecutor(
                4,//核心线程数
                10,//最大线程数
                60,//空闲时间数量
                TimeUnit.SECONDS,//空闲时间单位
                new LinkedBlockingQueue<>(),//阻塞队列
                new ThreadFactory() //线程创建的工厂类
                    @Override
                    public Thread newThread(Runnable r) 
                        return new Thread(r);
                    
                ,
                //拒绝策略
//                new ThreadPoolExecutor.CallerRunsPolicy()
//                new ThreadPoolExecutor.AbortPolicy()
//                new ThreadPoolExecutor.DiscardPolicy()
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );
        pool.execute(new Runnable() 
            @Override
            public void run() 
                System.out.println(1);
            
        );

3. 线程池执行的流程

4. 创建线程池

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

5. 停止线程池

可以通过调用线程池的shutdownshutdownNow方法来关闭线程池。它们的原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程,所以无法响应中断的任务可能永远无法终止。但是它们存在一定的区别。

  • shutDown() : 中断队列中的任务, 工作线程正在执行的任务, 还是会执行完毕才能关闭线程池
  • shutDownNow() : 中断队列中的任务, 及工作线程正在执行的任务

以上是关于多线程--线程池的主要内容,如果未能解决你的问题,请参考以下文章

Java线程池,这篇能让你和面试官聊了半小时

260期Java线程池,这篇能让你和面试官聊了半小时

如何设计一个实用的线程池?

JAVA线程池资源回收的问题

java如何在多线程执行完后才执行其他任务

java如何检查执行的线程已卡死