美丽寮步网站建设哪家好,esxi WordPress,惠州网站建设电话,wordpress旋转自动创建线程池就是直接调用 Executors去new默认的那几个线程池#xff0c;但是会出现一定的风险#xff0c;线程池里面会用到队列#xff0c;也会跟线程池自身有关#xff0c;所以要从队列和线程池两个方面去解析。
1.了解线程池的队列
线程池的内部结构主要由四部分组成…自动创建线程池就是直接调用 Executors去new默认的那几个线程池但是会出现一定的风险线程池里面会用到队列也会跟线程池自身有关所以要从队列和线程池两个方面去解析。
1.了解线程池的队列
线程池的内部结构主要由四部分组成
线程池管理器主要负责管理线程池的创建、销毁、添加任务等管理操作。工作线程从任务队列中获取任务并执行。任务队列作为一种缓冲机制线程池会把当下没有处理的任务放入任务队列中由于多线程同时从任务队列中获取任务是并发场景此时就需要任务队列满足线程安全的要求所以线程池中任务队列采用 BlockingQueue 来保障线程安全。任务任务要求实现统一的接口以便工作线程可以处理和执行。
在说下队列
1.LinkedBlockingQueue无界队列容量无限
对于 FixedThreadPool 和 SingleThreadExector 而言它们使用的阻塞队列是容量为 Integer.MAX_VALUE 的 LinkedBlockingQueue可以认为是无界队列。
由于 FixedThreadPool 线程池的线程数是固定的所以没有办法增加特别多的线程来处理任务这时就需要 LinkedBlockingQueue 这样一个没有容量限制的阻塞队列来存放任务。
这里需要注意由于线程池的任务队列永远不会放满所以线程池只会创建核心线程数量的线程所以此时的最大线程数对线程池来说没有意义因为并不会触发生成多于核心线程数的线程。
SynchronousQueue无限扩展线程数无限扩展
阻塞队列是 SynchronousQueue对应的线程池是 CachedThreadPool。
线程池 CachedThreadPool 的最大线程数是 Integer 的最大值可以理解为线程数是可以无限扩展的。
CachedThreadPool 和上一种线程池 FixedThreadPool 的情况恰恰相反FixedThreadPool 的情况是阻塞队列的容量是无限的而这里 CachedThreadPool 是线程数可以无限扩展所以 CachedThreadPool 线程池并不需要一个任务队列来存储任务因为一旦有任务被提交就直接转发给线程或者创建新线程来执行而不需要另外保存它们。
我们自己创建使用 SynchronousQueue 的线程池时如果不希望任务被拒绝那么就需要注意设置最大线程数要尽可能大一些以免发生任务数大于最大线程数时没办法把任务放到队列中也没有足够线程来执行任务的情况。
DelayedWorkQueue 延迟队列)
阻塞队列是DelayedWorkQueue它对应的线程池分别是 ScheduledThreadPool 和 SingleThreadScheduledExecutor这两种线程池的最大特点就是可以延迟执行任务比如说一定时间后执行任务或是每隔一定的时间执行一次任务。
DelayedWorkQueue 的特点是内部元素并不是按照放入的时间排序而是会按照延迟的时间长短对任务进行排序内部采用的是“堆”的数据结构。之所以线程池 ScheduledThreadPool 和 SingleThreadScheduledExecutor 选择 DelayedWorkQueue是因为它们本身正是基于时间执行任务的而延迟队列正好可以把任务按时间进行排序方便任务的执行。
2.为什么要自己创建线程池
看了上面的介绍其实已经已经知道了为啥了就是收到队列影响 产生内存不足 报错OOM。
在针对之前总结的集中做一个总结。
线程池使用队列风险FixedThreadPoolLinkedBlockingQueue大量堆积的任务会占用大量内存并发生 OOM 也就是OutOfMemoryErrorSingleThreadExecutorLinkedBlockingQueuenewSingleThreadExecutor 和 newFixedThreadPool 的原理是一样的只不过把核心线程数和最大线程数都直接设置成了 1但是任务队列仍是无界的 LinkedBlockingQueue所以也会导致同样的问题也就是当任务堆积时可能会占用大量的内存并导致 OOM。CachedThreadPoolSynchronousQueueSynchronousQueue 本身并不存储任务而是对任务直接进行转发但是最大线程数设置了 Integer.MAX_VALUE所以由于 CachedThreadPool 并不限制线程的数量当任务数量特别多的时候就可能会导致创建非常多的线程最终超过了操作系统的上限而无法创建新线程或者导致内存不足。ScheduledThreadPool 与SingleThreadScheduledExecutorDelayedWorkQueue延迟队列同时也是一个无界队列所以和 LinkedBlockingQueue 一样如果队列中存放过多的任务就可能导致 OOM
所以总结一下相比较而言我们自己手动创建会更好因为我们可以更加明确线程池的运行规则不仅可以选择适合自己的线程数量更可以在必要的时候拒绝新任务的提交避免资源耗尽的风险。