最代码官方的gravatar头像
最代码官方 2014-03-06 14:52:47

spring线程池ThreadPoolExecutor配置并且得到任务执行的结果

用ThreadPoolExecutor的时候,又想知道被执行的任务的执行情况,这时就可以用FutureTask。

ThreadPoolTask

package com.zuidaima.threadpool;

import java.io.Serializable;
import java.util.concurrent.Callable;

public class ThreadPoolTask implements Callable<String>, Serializable {

	private static final long serialVersionUID = 0;

	// 保存任务所需要的数据
	private Object threadPoolTaskData;

	private static int consumeTaskSleepTime = 2000;

	public ThreadPoolTask(Object tasks) {
		this.threadPoolTaskData = tasks;
	}

	public synchronized String call() throws Exception {
		// 处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句
		System.out.println("开始执行任务:" + threadPoolTaskData);
		String result = "";
		// //便于观察,等待一段时间
		try {
			// long r = 5/0;
			for (int i = 0; i < 100000000; i++) {

			}
			result = "OK";
		} catch (Exception e) {
			e.printStackTrace();
			result = "ERROR";
		}
		threadPoolTaskData = null;
		return result;
	}
}

模拟客户端提交的线程

package com.zuidaima.threadpool;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

public class StartTaskThread implements Runnable {

	private ThreadPoolTaskExecutor threadPoolTaskExecutor;
	private int i;

	public StartTaskThread(ThreadPoolTaskExecutor threadPoolTaskExecutor, int i) {
		this.threadPoolTaskExecutor = threadPoolTaskExecutor;
		this.i = i;
	}

	@Override
	public synchronized void run() {
		String task = "task@ " + i;
		System.out.println("创建任务并提交到线程池中:" + task);
		FutureTask<String> futureTask = new FutureTask<String>(
				new ThreadPoolTask(task));
		threadPoolTaskExecutor.execute(futureTask);
		// 在这里可以做别的任何事情
		String result = null;
		try {
			// 取得结果,同时设置超时执行时间为1秒。同样可以用future.get(),不设置执行超时时间取得结果
			result = futureTask.get(1000, TimeUnit.MILLISECONDS);
		} catch (InterruptedException e) {
			futureTask.cancel(true);
		} catch (ExecutionException e) {
			futureTask.cancel(true);
		} catch (Exception e) {
			futureTask.cancel(true);
			// 超时后,进行相应处理
		} finally {
			System.out.println("task@" + i + ":result=" + result);
		}

	}
}

SPRING配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		">
	<bean id="threadPoolTaskExecutor"
		class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">

		<!-- 核心线程数,默认为1 -->
		<property name="corePoolSize" value="10" />

		<!-- 最大线程数,默认为Integer.MAX_VALUE -->
		<property name="maxPoolSize" value="50" />

		<!-- 队列最大长度,一般需要设置值>=notifyScheduledMainExecutor.maxNum;默认为Integer.MAX_VALUE 
			<property name="queueCapacity" value="1000" /> -->

		<!-- 线程池维护线程所允许的空闲时间,默认为60s -->
		<property name="keepAliveSeconds" value="300" />

		<!-- 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 -->
		<property name="rejectedExecutionHandler">
			<!-- AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 -->
			<!-- CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度 -->
			<!-- DiscardOldestPolicy:抛弃旧的任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->
			<!-- DiscardPolicy:抛弃当前任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->
			<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
		</property>
	</bean>
</beans>

测试类

package com.zuidaima.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.zuidaima.threadpool.StartTaskThread;

@RunWith(SpringJUnit4ClassRunner.class)
// 指定的运行runner,并且把你所指定的Runner作为参数传递给它
@ContextConfiguration(locations = "classpath*:applicationContext.xml")
public class TestThreadPool extends AbstractJUnit4SpringContextTests {

	private static int produceTaskSleepTime = 10;

	private static int produceTaskMaxNumber = 1000;

	@Autowired
	private ThreadPoolTaskExecutor threadPoolTaskExecutor;

	public ThreadPoolTaskExecutor getThreadPoolTaskExecutor() {
		return threadPoolTaskExecutor;
	}

	public void setThreadPoolTaskExecutor(
			ThreadPoolTaskExecutor threadPoolTaskExecutor) {
		this.threadPoolTaskExecutor = threadPoolTaskExecutor;
	}

	@Test
	public void testThreadPoolExecutor() {
		for (int i = 1; i <= produceTaskMaxNumber; i++) {
			try {
				Thread.sleep(produceTaskSleepTime);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			new Thread(new StartTaskThread(threadPoolTaskExecutor, i)).start();
		}

	}

}

原文中有些纰漏,我已经修改

项目截图(基于maven构建)

spring线程池ThreadPoolExecutor配置并且得到任务执行的结果

运行截图:

spring线程池ThreadPoolExecutor配置并且得到任务执行的结果

如果遇到cpu忙执行超过1秒的会返回null

spring线程池ThreadPoolExecutor配置并且得到任务执行的结果


打赏

文件名:zuidaima_ThreadPoolTaskExecutor.rar,文件大小:4.818K 下载
最代码最近下载分享源代码列表最近下载
heweimin  LV13 2023年7月27日
2469095052  LV8 2022年5月27日
mylzdy  LV12 2022年5月12日
huasir2018  LV14 2020年5月25日
宇文笑  LV5 2019年8月29日
太阳暖人不暖心  LV7 2019年5月7日
1943815081  LV13 2019年1月2日
zinshao  LV12 2018年11月24日
h895413025  LV1 2018年11月13日
1633788059  LV12 2018年5月25日
最代码最近浏览分享源代码列表最近浏览
yyh1252  LV8 2023年11月23日
heweimin  LV13 2023年7月27日
微信网友_15002431817 2023年1月17日
暂无贡献等级
1529860026  LV24 2022年9月5日
mylzdy  LV12 2022年5月12日
1234mama  LV19 2022年3月22日
shaoluyu  LV4 2022年3月18日
2469095052  LV8 2021年12月29日
gaojian0612  LV2 2021年11月23日
随便取个名字_哈哈  LV27 2021年11月7日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友