自定义实现Java线程池-完善异常处理和去除同步


本篇文章将延续上篇文章的思路继续完善线程池执行功能,主要完善execute方法线程安全的前提下去除同步锁和对任务执行异常的处理,上篇文章最终代码如下:

@Override
public void execute(Runnable command) {
    
	// 校验参数有效性
	if (command == null)
		throw new NullPointerException("command is null ...");

	// 如果实际线程数量小于核心线程数,
	if (getWorkCount() < coreThreadPool)
		// 初始化线程执行任务
		addThread(command);
	else if (workQueue.offer(command)) {
    
		// 任务放入队列成功,校验核心线程是否为0
		if (getWorkCount() == 0)
			// 初始化一条不携带任务的线程,让它从队列中获取任务
			addThread(null);
	} else if (getWorkCount() < maxThreadPool) {
    
		// 初始化非核心线程
		addThread(command);
	} else if (getWorkCount() >= maxThreadPool)
		// 提交任务过多,线程池处理过不来,抛出异常
		throw new RejectedExecutionException(
				"command id too much, reject execute ...");
}

private synchronized void addThread(Runnable task) {
    
	// 由于execute方法调用addThread(null),此处参数非空校验得去掉
	// 去掉不保证会有代码恶意调用,所以此方法不能泄露,必须用private修饰

	// 为保证代码健壮性,常规参数校验
	// if (task == null)
	// throw new NullPointerException("taks is null ...");

	// 增加一条线程
	increaseWork();
	new Worker(task).thread.start();
}

// 提供getTask方法从队列中取值
private Runnable getTask() {
    
	boolean timeOut = false;
	for (;;) {
    
		boolean timed = getWorkCount() > coreThreadPool;
		
		// 利用timed和timeOut一起判断线程是否应该死亡
		if (timed && timeOut) {
    
			// 线程即将死亡,wc自减1
			decreaseWork();
			// 返回为空意味着跳出while循环,线程即将死亡
			return null;
		}
		try {
    
			// 从队列中取值
			Runnable task = timed ? workQueue.poll(keepAliveTime, 
					TimeUnit.NANOSECONDS) : workQueue.take();
			if (task != null)
				return task;
			// 非核心线程获取超时,直接返回null,跳到循环初始处再次和
			// timed变量判断,防止核心线程死亡
			timeOut = true;
		} catch (
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值