juc - 线程池的使用

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;

/**
 * @description: 测试使用线程池
 */
public class TestThreadPool {

	public static void main(String[] args) {
		//核心线程个数
		int corePoolSize = 2;
		//最大线程数量
		int maximumPoolSize = 4;
		//创建了超出核心线程个数的线程(临时线程)后,当该线程空闲下来可能会被销毁
		//线程允许空闲时间(线程在空闲状态下,在允许空闲时间内不会销毁)
		//TimeUnit表示允许线程空闲时间的单位
		long keepAliveTime = 1L;
		//等待队列
		BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1024);
		//线程池饱和策略
		RejectedExecutionHandler policy = new RejectedDiscardPolicy("taskId");
		ExecutorService executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, queue, policy);
		for (int i = 0; i < 100000; i++) {
			executor.execute(new Worker());
		}

		//慎用shutdownNow(立即关闭线程池,不管队列中的任务是否执行完)
//		executorService.shutdownNow();
		//推荐使用shutdown去关闭线程池,这个方法会等待队列中的任务全部执行完才去关闭线程池
		executor.shutdown();
	}


}

class Worker implements Runnable {

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "正在执行");
	}
}


/**
 * @description: 自定义饱和策略(中止策略也是默认策略)
 */
class RejectedAbortPolicy implements RejectedExecutionHandler {
	/**
	 * 执行任务的标识
	 */
	private String taskId;

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public RejectedAbortPolicy(String taskId) {
		this.taskId = taskId;
	}

	/**
	 * @description: 使用该策略时在饱和时会抛出RejectedExecutionException(继承自RuntimeException),调用者可捕获该异常自行处理。
	 */
	@Override
	public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
		throw new RejectedExecutionException(taskId +
				" rejected from " +
				executor.toString());
	}
}

/**
 * @description: 自定义饱和策略(抛弃策略)
 */
class RejectedDiscardPolicy implements RejectedExecutionHandler {
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	/**
	 * 执行任务的标识
	 */
	private String taskId;

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public RejectedDiscardPolicy(String taskId) {
		this.taskId = taskId;
	}

	/**
	 * @description: 不做任何处理直接抛弃任务
	 */
	@Override
	public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
		//计划执行的大致任务数
		String taskCount = String.valueOf(executor.getTaskCount());
		//正在执行任务的大致线程数
		String activeCount = String.valueOf(executor.getActiveCount());
		//不处理使用抛弃策略
		logger.error("RejectedDiscardPolicy.rejectedExecution, taskId :{}, task count: {}, active thread: {}", taskId,
				taskCount, activeCount);
	}

}

/**
 * @description: 自定义饱和策略(抛弃旧任务策略)
 */
class RejectedDiscardOldestPolicy implements RejectedExecutionHandler {
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	/**
	 * 执行任务的标识
	 */
	private String taskId;

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public RejectedDiscardOldestPolicy(String taskId) {
		this.taskId = taskId;
	}

	/**
	 * @description: 先将阻塞队列中的当前任务抛弃,再尝试提交任务。如果此时阻塞队列使用PriorityBlockingQueue优先级队列,将会导致优先级最高的任务被抛弃,因此不建议将该种策略配合优先级队列使用。
	 */
	@Override
	public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
		if (!executor.isShutdown()) {
			executor.getQueue().poll();
			executor.execute(r);
		}
		logger.error("RejectedDiscardOldestPolicy.rejectedExecution,taskId:{}", taskId);
	}

}


/**
 * @description: 自定义饱和策略(调用者运行)
 */
class RejectedCallerRunsPolicy implements RejectedExecutionHandler {
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	/**
	 * 执行任务的标识
	 */
	private String taskId;

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public RejectedCallerRunsPolicy(String taskId) {
		this.taskId = taskId;
	}

	/**
	 * @description: 既不抛弃任务也不抛出异常,直接运行任务的run方法,换言之将任务回退给调用者来直接运行。
	 * 使用该策略时线程池饱和后将由调用线程池的主线程自己来执行任务,
	 * 因此在执行任务的这段时间里主线程无法再提交新任务,从而使线程池中工作线程有时间将正在处理的任务处理完成。
	 */
	@Override
	public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
		if (!executor.isShutdown()) {
			r.run();
		}
		logger.warn("RejectedCallerRunsPolicy.rejectedExecution,taskId:{}", taskId);
	}

}

代码参考博文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值