1、常用的四种线程池
Executors类中提供的几个静态方法来创建线程池:
- newCachedThreadPool 缓存线程池
- newFixedThreadPool 固定线程数线程池
- newSingleThreadExecutor 单线程线程池
- newScheduledThreadPool 定时和周期性任务执行的定长线程池
2、线程池的说明及使用
- newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。大小最大可以达到Integer.MAX_VALUE。源码如下:
- newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。源码如下:
- newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。源码如下:
- newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。源码如下:
3、线程池在java中的使用
package com.yw.thread; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MyThreadPool { private static Integer THREAD_POOL_NUM = 50; public static void main(String[] args) throws Exception{ List<String> list = new ArrayList<String>(); list.add("章程"); list.add("流苏"); list.add("漾须"); Map<String, String> map = new HashMap<String, String>(); //使用newCachedThreadPool作为示例 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); //ExecutorService fixedThreadPool = Executors.newFixedThreadPool(MyThreadPool.THREAD_POOL_NUM); //ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); //ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(MyThreadPool.THREAD_POOL_NUM); for (int i=0; i<10; i++) { cachedThreadPool.execute(new testFor(list, map)); } cachedThreadPool.shutdown(); while (true) { if (cachedThreadPool.isTerminated()) { System.out.println("多线程执行完毕"); break; } Thread.sleep(200); } System.out.println("执行完毕==========================="); System.out.println(map.toString()); } } class testFor implements Runnable{ private List<String> list; private Map<String, String> map; public testFor(List<String> list, Map<String, String> map) { this.list = list; this.map = map; } @Override public void run() { for (int i = 0; i < list.size(); i++) { System.out.println(Thread.currentThread().getName()+"="+list.get(i)); map.put(Thread.currentThread().getName()+ "----" + i, list.get(i)); } } }
4、ThreadPoolExecutor类
从上面源码可以看到,Executor提供的四个创建线程池的静态方法中,最终都是调用ThreadPoolExecutor的构造函数来实现,下面就来介绍一下ThreadPoolExecutor。
- 首先介绍下各个类的关系:
java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,它提供了四个构造方法和一个执行方法(execute):
public class ThreadPoolExecutor extends AbstractExecutorService { ...... public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; } public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command); } ...... }
构造器中各个参数的含义:
- corePoolSize:核心池大小。在创建线程池后,默认情况下,线程池中没有任何线程,等待有任务来了才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者怕热startCoreThread()方法,这个两个方法就是与创建线程的意思,即在没有任务来之前就创建corePoolSize个线程或一个线程。当线程池中的线程数目达到corePoolSize后,就会把到达的线程任务放到缓存队列中。
- maximumPoolSize:线程池最大线程数。表示在线程池中最多能创建多少个线程。
- keepAliveTime:线程没有任务执行时最多保持多久时间会终止。时间单位参考unit。
- unit:参数keepAliveTime的时间单位,有7种取值,TimeUnit类中有7种静态属性。
TimeUnit.NANOSECONDS; //纳秒 TimeUnit.MICROSECONDS; //微妙 TimeUnit.MILLISECONDS; //毫秒 TimeUnit.SECONDS; //秒 TimeUnit.MINUTES; //分钟 TimeUnit.HOURS; //小时 TimeUnit.DAYS; //天
- workQueue:一个阻塞队列,用来存数等待执行的任务。一般使用LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关。
- threadFactory:线程工厂,主要用来创建线程。
- handler:表示当拒绝处理任务时的策略,有四种取值:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程) ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
参考资料:
http://www.cnblogs.com/dolphin0520/p/3932921.html