Java并发-ThreadPoolExecutor线程池中BlockingQueue的三种实现

首先先看一下ThreadPoolExecutor线程池的构造方法

ThreadPoolExecutor
(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory,RejectedExecutionHandler handler)

这里主要需要了解四个关键字

int corePoolSize

线程池的基础大小(核心线程数),默认情况下核心线程会一直存活,即使处于闲置状态也不会受存keepAliveTime限制

当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。

maximumPoolSize

线程池所能容纳的最大线程数。超过这个数的线程将被阻塞。不要理解为线程池所能创建的线程数,线程池会根据不同的情况(即使用哪种BlockingQuene)来确定最多创建多少线程, 而且不能理解为同一时间能创建maxmunPooSize个线程, 需要根据BlockingQuene来区别。 先不讲解, 后面详细说明,这里单单提出一种: 当任务队列(workQueue)为没有设置大小的LinkedBlockingDeque时(详看下面这一行代码),maximunPoolSize这个值无效.

threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,new LinkedBlockingDeque<>())
keepAliveTime

非核心线程的闲置超时时间,超过这个时间就会被回收

unit

指定keepAliveTime的单位,如TimeUnit.SECONDS。当将allowCoreThreadTimeOut设置为true时对corePoolSize生效

workQueue

任务队列(阻塞队列)用于保存等待执行的任务的阻塞队列, 有以下三种阻塞队列

SynchronousQueue,LinkedBlockingDeque,ArrayBlockingQueue

  1. SynchronousQueue:一个不存储元素的阻塞队列。可以理解为没有阻塞队列,如果超过核心线程数量时,则直接创建非核心线程, 除非超过maxMumPoolSize报Java.util.concurrent.RejectedExecutionException
  2. LinkedBlockingQuene: 可以无界,可以有界。 是一个基于链表的阻塞队列,吞吐量通常高于ArrayBlockingQueue(LinkedBlockingQuene 使用两个锁来控制线程访问,这样队列可以同时进行put和take的操作,因此通途量相对高),静态工厂方法Executors.newFilxedThreadPool()使用这个队列  
  3. ArrayListBlockingQueue是有界的,是一个有界缓存的阻塞队列

new LinkedBlockingQueue<>(30)  //有界 new LinkedBlockingQueue<>()  //无界

最后总结一下线程池的规则

  1. 如果运行的线程少于 corePoolSize,则 Executor 始终首选添加新的线程,及时核心线程有空闲的
  2. 如果运行的线程等于或多于 corePoolSize,则 Executor 始终首选将请求加入队列WorkQueue,而不添加新的线程。
  3. 如果无法将请求加入队列 (如SynchronousQueue)或者队列已满,则创建非核心线程,除非创建此线程超出 maximumPoolSize,如果超过,在这种情况下,新的任务么就会根据拒绝策略来拒绝执行

测试

  通过设置以下红色部分的值来校验结果

public class TestThreadPool {
	
	static CountDownLatch count =  null;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List list = new ArrayList();
		for(int i= 1; i <= 200; i++){
			list.add("list" + i);
		}
		count = new CountDownLatch(list.size());
		
		List> callableList = new ArrayList<>();
		
		for (int i = 0; i < list.size(); i++) {
			final String listName = list.get(i);
			TestCallable callable = new TestCallable<>(listName);
			callableList.add(callable);
		}
		List> futures = ThreadPoolUtil.exeCallableList(callableList);
		System.err.println("下一个task。。");
		ThreadPoolUtil.shutDown(true);
		
	}

}
package com.yaya.thread.future;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolUtil {

	// 线程池
	private static ThreadPoolExecutor threadPool;

	// 线程池核心线程数
	private static final int CORE_POOL_SIZE = 3;

	// 线程池最大线程数
	private static final int MAX_POOL_SIZE = 20;

	// 额外线程空状态生存时间
	private static final int KEEP_ALIVE_TIME = 10000;

	private static final int CANCEL_TASK_TIME = 20;

	private ThreadPoolUtil() {

	}

	static {
		threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
				new LinkedBlockingQueue<>(30), new ThreadFactory() {
					private final AtomicInteger integer = new AtomicInteger();

					@Override
					public Thread newThread(Runnable r) {
						return new Thread(r, "mock thread:" + integer.getAndIncrement());
					}
				});
	}

	/**
	 * 从线程池中抽取线程,执行指定的Runnable对象
	 * 
	 * @param runnable
	 */
	public static void execute(Runnable runnable) {
		threadPool.execute(runnable);
	}

	/**
	 * 批量执行 Runnable任务
	 * 
	 * @param runnableList
	 */
	public static void exeRunnableList(List runnableList) {
		for (Runnable runnable : runnableList) {
			threadPool.execute(runnable);
		}
	}

	/**
	 * 从线程池中抽取线程,执行指定的Callable对象
	 * 
	 * @param callable
	 * @return 返回执行完毕后的预期结果
	 */
	public static Future exeCallable(Callable callable) {
		return threadPool.submit(callable);
	}

	/**
	 * 批量执行 Callable任务
	 * 
	 * @param callableList
	 *            callable的实例列表
	 * @return 返回指定的预期执行结果
	 */
	public static List> exeCallableList(List> callableList) {
		List> futures = null;
		try {
			futures = threadPool.invokeAll(callableList);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return futures;
	}

	/**
	 * 中断任务的执行
	 * 
	 * @param isForceClose
	 *            true:强制中断 false:等待任务执行完毕后,关闭线程池
	 */
	public static void shutDown(boolean isForceClose) {
		if (isForceClose) {
			threadPool.shutdownNow();
		} else {
			threadPool.shutdown();
		}
	}

	/**
	 * 若超出CANCEL_TASK_TIME的时间,没有得到执行结果,则尝试中断线程
	 * 
	 * @param future
	 * @return 中断成功,则返回true 否则返回false
	 */
	public static boolean attemptCancelTask(Future future) {
		boolean cancel = false;
		try {
			future.get(CANCEL_TASK_TIME, TimeUnit.MINUTES);
			cancel = true;
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			cancel = future.cancel(true);
			e.printStackTrace();
		}
		return cancel;
	}
	
}
package com.yaya.thread.future;


public class TestCallable implements Callable {

    String appid;

    public TestCallable(java.lang.String appid) {
        this.appid = (String) appid;
    }

    @Override
    public String call() throws Exception {
//        Thread.sleep(1000);
//        System.err.println("task" + this.appid + "睡了1s");
        Thread.sleep(3000);
        System.err.println("task" + this.appid+"睡了3s");
        
//        System.err.println("task" + this.appid + "睡了3s");
        return (String) ("task" + this.appid+ " return");
    }
}




你可能感兴趣的:(Java,Java并发)