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:由调用线程处理该任务