Java线程池

根据《阿里巴巴java编程规范》,线程池的创建必须使用 new ThreadPoolExecutor() 来创建

//	构建函数一共有七个参数:
//	核心线程数:不会关闭的线程数
//	最大线程数:最多可以同时运行的线程数
//	超时等待:当线程池没满的时候为了节约资源,要关闭一部分线程
//	超时等待单位:和上面的配合使用
//	阻塞队列:排队的队列
//	线程池工厂:创建线程的工厂,如何创建线程
//	拒绝策略:任务太多时的拒绝策略
ThreadPoolExecutor executor = new ThreadPoolExecutor();
//	超时等待的单位
	TimeUnit.DAYS;               //天
	TimeUnit.HOURS;             //小时
	TimeUnit.MINUTES;           //分钟
	TimeUnit.SECONDS;           //秒
	TimeUnit.MILLISECONDS;      //毫秒
	TimeUnit.MICROSECONDS;      //微妙
	TimeUnit.NANOSECONDS;       //纳秒java
//	阻塞队列的一般选择
	ArrayBlockingQueue;
	LinkedBlockingQueue;
	SynchronousQueue;
	ThreadPoolExecutor.AbortPolicy;//丢弃任务并抛出RejectedExecutionException异常。 
	ThreadPoolExecutor.DiscardPolicy;//也是丢弃任务,但是不抛出异常。 
	ThreadPoolExecutor.DiscardOldestPolicy;//丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
	ThreadPoolExecutor.CallerRunsPolicy;//由调用线程处理该任务 
public class ThreadPoolTest {

	public static void main(String[] args) {
		ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 20, 200, TimeUnit.MILLISECONDS,
				new ArrayBlockingQueue<Runnable>(5), Executors.defaultThreadFactory(),
				new ThreadPoolExecutor.AbortPolicy());
		for (int i = 0; i < 20; i++) {
			Task task = new Task(i);
			executor.execute(task);
		}
	}
}

class Task implements Runnable {
	private int taskNum;

	public Task(int num) {
		this.taskNum = num;
	}

	@Override
	public void run() {
		System.out.println("正在执行task " + taskNum);
		try {
			Thread.sleep((int) (Math.random()));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("task " + taskNum + "执行完毕");
	}
}

关于不同的线程数时线程池的状态:

  • 0 < 线程数 <= 核心线程数:直接运行
  • 核心线程数 < 线程数 <= 最大线程数:如果线程池中多于核心线程但少于最大线程的那部分线程没有关闭,则直接添加执行;如果关闭了则先加入阻塞队列,待线程池创建线程后从阻塞队列取出任务执行
  • 最大线程数 < 线程数 <= 最大线程数+阻塞队列长度:等待线程池中有空闲线程后从阻塞队列取出任务执行
  • 最大线程数+阻塞队列长度 < 线程数:执行拒绝策略
原文地址:https://www.cnblogs.com/cdbb/p/12558072.html