多线程两种方式:

1.通过 Executors 工厂方法创建

2.通过 new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) 自定义创建 

相对而言,更建议用第二个创建线程池,Executors 创建的线程池内部很多地方用到了无界任务队列,在高并发场景下,无界任务队列会接收过多的任务对象,严重情况下会导致 JVM 崩溃,一些大厂也是禁止使用 Executors 工厂方法去创建线程池。newFixedThreadPool 和 newSingleThreadExecutor 的主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM;newCachedThreadPool 和 newScheduledThreadPool 的主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。

 

new ThreadPoolExecutor描述:

public ThreadPoolExecutor(

int corePoolSize,//线程池核心线程大小

int maximumPoolSize,//线程池最大线程数量

long keepAliveTime,//空闲线程存活时间

TimeUnit unit,//空闲线程存活时间单位,一共有七种静态属性(TimeUnit.DAYS天,TimeUnit.HOURS小时,TimeUnit.MINUTES分钟,TimeUnit.SECONDS秒,TimeUnit.MILLISECONDS毫秒,TimeUnit.MICROSECONDS微妙,TimeUnit.NANOSECONDS纳秒)

BlockingQueue<Runnable> workQueue,//工作队列

ThreadFactory threadFactory,//线程工厂,主要用来创建线程(默认的工厂方法是:Executors.defaultThreadFactory()对线程进行安全检查并命名)

RejectedExecutionHandler handler//拒绝策略(默认是:ThreadPoolExecutor.AbortPolicy不执行并抛出异常)) 

使用示例:

ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 20, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<>(5));5.2.1、工作队列

jdk 中提供了四种工作队列:①ArrayBlockingQueue 基于数组的有界阻塞队列,按 FIFO 排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到 corePoolSize 后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到 maxPoolSize,则会执行拒绝策略。 ②LinkedBlockingQuene 基于链表的无界阻塞队列(其实最大容量为 Interger.MAX_VALUE),按照 FIFO 排序。由于该队列的近似无界性,当线程池中线程数量达到 corePoolSize 后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到 maxPoolSize,因此使用该工作队列时,参数 maxPoolSize 其实是不起作用的。 ③SynchronousQuene 一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到 maxPoolSize,则执行拒绝策略。 ④PriorityBlockingQueue 具有优先级的无界阻塞队列,优先级通过参数 Comparator 实现。

 

注:原地址链接https://baijiahao.baidu.com/s?id=1682037854549644761&wfr=spider&for=pc

 

 

 

posted on 2022-05-17 16:27  茫无所知  阅读(125)  评论(0编辑  收藏  举报