线程池(java.util.concurrent.ThreadPoolExecutor)的使用(二)

Executor 已经关闭,并且 Executor 将有限边界用于最大线程和工作队列容量,且已经饱和时,在方法 execute(java.lang.Runnable) 中提交的新任务将被拒绝。在以上两种情况下,execute 方法都将调用其 RejectedExecutionHandler RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) 方法。下面提供了四种预定义的处理程序策略:

A.        在默认的 ThreadPoolExecutor.AbortPolicy 中,处理程序遭到拒绝将抛出运行时 RejectedExecutionException

B.        ThreadPoolExecutor.CallerRunsPolicy 中,线程调用运行该任务的 execute 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。

C.        ThreadPoolExecutor.DiscardPolicy 中,不能执行的任务将被删除。

D.        ThreadPoolExecutor.DiscardOldestPolicy 中,如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)。

定义和使用其他种类的 RejectedExecutionHandler 类也是可能的,但这样做需要非常小心,尤其是当策略仅用于特定容量或排队策略时。

 

挂钩方法

此类提供 protected 可重写的 beforeExecute(java.lang.Thread, java.lang.Runnable) afterExecute(java.lang.Runnable, java.lang.Throwable) 方法,这两种方法分别在执行每个任务之前和之后调用。它们可用于操纵执行环境;例如,重新初始化 ThreadLocal、搜集统计信息或添加日志条目。此外,还可以重写方法 terminated() 来执行 Executor 完全终止后需要完成的所有特殊处理。

 

如果挂钩或回调方法抛出异常,则内部辅助线程将依次失败并突然终止。

 

队列维护

方法 getQueue() 允许出于监控和调试目的而访问工作队列。强烈反对出于其他任何目的而使用此方法。remove(java.lang.Runnable) purge() 这两种方法可用于在取消大量已排队任务时帮助进行存储回收。

 

一、例子

 

创建 TestThreadPool 类:

 

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestThreadPool {

	private static int produceTaskSleepTime = 2;
	
	private static int produceTaskMaxNumber = 10;

	public static void main(String[] args) {

		// 构造一个线程池
		ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
				TimeUnit.SECONDS, new ArrayBlockingQueue(3),
				new ThreadPoolExecutor.DiscardOldestPolicy());

		for (int i = 1; i <= produceTaskMaxNumber; i++) {
			try {
				String task = "task@ " + i;
				System.out.println("创建任务并提交到线程池中:" + task);
				threadPool.execute(new ThreadPoolTask(task));

				Thread.sleep(produceTaskSleepTime);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

 

 

 

创建 ThreadPoolTask类:

        

import java.io.Serializable;

public class ThreadPoolTask implements Runnable, Serializable {

	private Object attachData;

	ThreadPoolTask(Object tasks) {
		this.attachData = tasks;
	}

	public void run() {
		
		System.out.println("开始执行任务:" + attachData);
		
		attachData = null;
	}

	public Object getTask() {
		return this.attachData;
	}
}

 

 

         执行结果:

               创建任务并提交到线程池中:task@ 1

开始执行任务:task@ 1

创建任务并提交到线程池中:task@ 2

开始执行任务:task@ 2

创建任务并提交到线程池中:task@ 3

创建任务并提交到线程池中:task@ 4

开始执行任务:task@ 3

创建任务并提交到线程池中:task@ 5

开始执行任务:task@ 4

创建任务并提交到线程池中:task@ 6

创建任务并提交到线程池中:task@ 7

创建任务并提交到线程池中:task@ 8

开始执行任务:task@ 5

开始执行任务:task@ 6

创建任务并提交到线程池中:task@ 9

开始执行任务:task@ 7

创建任务并提交到线程池中:task@ 10

开始执行任务:task@ 8

开始执行任务:task@ 9

开始执行任务:task@ 10

你可能感兴趣的:(软件,-,JAVA)