4种JDK自带线程池介绍
一、4种基本线程池
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
1.newCachedThreadPool可缓存线程池
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
- 这种线程池内部没有核心线程,线程的数量是有没限制的。
- 在创建任务时,若有空闲的线程时则复用空闲的线程,若没有则新建线程。
- 没有工作的线程(闲置状态)在超过了60S还不做事,就会销毁。
2.FixedThreadPool 定长线程池
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
- 该线程池的最大线程数等于核心线程数,所以在默认情况下,该线程池的线程不会因为闲置状态超时而被销毁。
- 如果当前线程数小于核心线程数,并且也有闲置线程的时候提交了任务,这时也不会去复用之前的闲置线程,会创建新的线程去执行任务。如果当前执行任务数大于了核心线程数,大于的部分就会进入队列等待。等着有闲置的线程来执行这个任务。
3.SingleThreadPool
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
- 有且仅有一个工作线程执行任务
- 所有任务按照指定顺序执行,即遵循队列的入队出队规则
4.ScheduledThreadPool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } //ScheduledThreadPoolExecutor(): public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); }
DEFAULT_KEEPALIVE_MILLIS就是默认10L,这里就是10秒。这个线程池有点像是吧CachedThreadPool和FixedThreadPool 结合了一下。
- 不仅设置了核心线程数,最大线程数也是Integer.MAX_VALUE。
- 这个线程池是上述4个中为唯一个有延迟执行和周期执行任务的线程池。
二、例子
package xu.threadPool; import java.util.concurrent.*; import java.util.concurrent.locks.AbstractQueuedSynchronizer; public class poolMain { public static void main(String[] arg0) throws Exception { int corePoolSize = 10; //核心线程数 int maximumPoolSize = 50; //最大线程数 long keepAliveTime = 1000; //非核心线程的休眠时间 TimeUnit.MILLISECONDS 毫秒 BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(1000); //大小1000的阻塞队列 ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 默认线程工厂 RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); //默认拒绝规则,直接异常 ThreadPoolExecutor pool = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit.MILLISECONDS,workQueue,threadFactory,handler); for(int i = 0 ; i<10;i++){ pool.execute(new threadCMD("threa" + i)); } //获取值的线程池 Future future = pool.submit(new callableCMD("callable")); System.out.println("开始尝试获取返回值:"); System.out.println("获取到内容:" + future.get());//get是阻塞的。 pool.shutdown();//关闭线程池,队列中会继续执行。 System.out.println("shutDown完成"); ScheduledExecutorService schedulePool = Executors.newScheduledThreadPool(1); schedulePool.schedule(new threadCMD("定时任务schedule"),1000,TimeUnit.MILLISECONDS); schedulePool.scheduleWithFixedDelay(new threadCMD("循环任务schedule"),0,1000,TimeUnit.MILLISECONDS);//表示以固定延时执行任务,延时是相对当前任务结束为起点计算开始时间。 schedulePool.scheduleAtFixedRate(new threadCMD("循环任务schedule2"),0,1000,TimeUnit.MILLISECONDS);//表示以固定频率执行的任务,如果当前任务耗时较多,超过定时周期period,则当前任务结束后会立即执行。 } }
package xu.threadPool; import java.util.Date; public class threadCMD implements Runnable { String name; threadCMD(String name){ this.name = name; } public void run() { try { System.out.println("线程" + name + ":运行时间" + new Date()); Thread.sleep(2000); }catch (Exception e){ e.printStackTrace(); } } }
package xu.threadPool; import java.util.concurrent.Callable; public class callableCMD implements Callable<String> { String name; callableCMD(String name){ this.name = name; } public String call() throws Exception { System.out.println("线程" + name +":运行,休眠1000ms"); Thread.sleep(1000); System.out.println("线程" + name +":休眠结束"); return name; } }