创建线程池可以分为三种方式:
1. 通过ThreadPoolExecutor的构造方法,创建ThreadPoolExecutor的对象,即一个线程池对象;
此构造方法,一共7个参数,5个必须参数,2个带有默认值的参数;详细后面说;
传送:https://www.cnblogs.com/mussessein/p/11654022.html
2. 通过Executors返回的线程池对象;
这种方法创建的常用线程池为4种,还可以创建ForkJoinPool对象;
可以说是封装好的方法,通过Executors的4种常用静态方法,返回4种已经封装好的ThreadPoolExecutor线程池对象;
传送:https://www.cnblogs.com/mussessein/p/11654120.html
3. ForkJoinPool并发框架
将一个大任务拆分成多个小任务后,使用fork可以将小任务分发给其他线程同时处理,使用join可以将多个线程处理的结果进行汇总;这实际上就是分治思想。
Executor类(尽量不使用此方法,而是使用ThreadPoolExecutor类)
Executors 返回的线程池对象的弊端如下:
-
FixedThreadPool 和 SingleThreadPool : 允许的请求队列长度为 Integer.MAX_VALUE ,可能会堆积大量的请求,从而导致 OOM 。
-
CachedThreadPool 和 ScheduledThreadPool : 允许的创建线程数量为 Integer.MAX_VALUE ,可能会创建大量的线程,从而导致 OOM 。
只要用于返回ExecutorService对象
四种方法都返回一个ExecutorService的实现类ThreadPoolExecutor的实例对象,创建四种不同的线程池。
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
-
创建固定数目线程的线程
-
缓存队列:LinkedBlockingQueue:*阻塞队列,队列最大值为Integer.MAX_VALUE,如果任务提交速度持续大余任务处理速度,会造成队列大量阻塞。
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
-
创建一个可缓存的线程池
-
缓存队列:SynchronousQueue 同步队列
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor (1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
-
创建一个单线程化的线程池,其中corePoolSize,maximumPoolSize,都为1,即只有一个线程在运行。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); }
-
创建一个支持定时及周期性的任务执行的线程池
演示:
使用线程池的一般步骤:
-
创建线程:Runnable实现类、Callable实现类
-
调用Executors类的静态工厂方法创建一个ExecutorService的实例对象,一个线程池创建成功
-
调用ExecutorService对象的submit方法提交线程
-
shutdown方法关闭线程池。
public static void main(String[] args){ // 创建一个具有固定线程数6的线程池 ExecutorService pool= Executors.newFixedThreadPool(6); // 使用lambda创建Runnable对象 Runnable target=()->{ for (int i=0;i<20;i++){ System.out.println(Thread.currentThread().getName()+"---i值:"+i); } }; // 向线程池提交两个线程 pool.submit(target); pool.submit(target); //关闭线程池 pool.shutdown(); }