说明:
(1)本篇博客的主要内容:
● 是演示JDK给我们提供的4种自动创建线程的方式;可以得出【不推荐采用自动创建线程的方式,去创建线程】的结论;
● 自己根据具体需求,创建线程池时,线程数量的确定原则;
目录
二:我们可以直接调用JDK封装好的构造方法,去自动创建线程池;但这可能会带来一些问题;
1.自动创建线程池的策略一:Executors.newFixedThreadPool();
2.自动创建线程池的策略二:Executors.newSingleThreadExecutor();
3.自动创建线程池的策略三:Executors.newCachedThreadPool();
4.自动创建线程池的策略四:Executors.newScheduledThreadPool();
三:所以,比较合适的做法是:根据自己的业务场景去设置线程池参数,手动创建线程池;
一:线程池应该手动创建还是自动创建?:应该手动创建;
手动创建更好,因为这样可以更加明确线程池的运行规则,避免资源耗尽的风险;
自动创建线程,会带来一些问题;
二:我们可以直接调用JDK封装好的构造方法,去自动创建线程池;但这可能会带来一些问题;
1.自动创建线程池的策略一:Executors.newFixedThreadPool();
package threadPool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 演示JDK提供的自动创建线程池的方法:newFixedThreadPool(); */ public class FixedThreadPoolTest { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(4); for (int i = 0; i <100 ; i++) { executorService.execute(new TaskTest()); } } } /** * 任务; * 这个任务,仅仅用于演示; */ class TaskTest implements Runnable { @Override public void run() { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); } }
说明:
(1)程序内容说明;(这部分不是重点啦)
(2)newFixedThreadPool(int nThreads)原理分析;
● 这种线程池的特点:核心线程数和最大线程数相同,都设置为我们传递参数大小;队列使用的是无界队列;
● 那么很显然,对于这种线程池;因为队列是无界队列,所以,如果任务很多处理不完的时候,任务就可能会堆积在队列中,从而产生OOM错误;
● 这种线程池为什么要使用无界队列?:因为,无界队列可以满足这种线程池功能;;;;因为,这种线程池,最大线程数和核心线程数相同,那么当任务很多的时候,我们不得不使用无界队列去存储新来的任务;
(3)演示OOM内存溢出异常;
package threadPool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 演示JDK提供的自动创建线程池的方法:newFixedThreadPool():产生OOM错误的情况; */ public class FixedThreadPoolOOM { //为了能更对的把任务弄到队列中,更好的能看到OOM的效果,我们这个线程池的线程数设为了1 private static ExecutorService executorService = Executors.newFixedThreadPool(1); public static void main(String[] args) { for