我使用了spring线程池,配置如下
<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>
package com.ht.thread;
import java.io.Serializable;
import java.util.concurrent.Callable;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.ht.bean.Emp;
import com.ht.dao.IEmpDao;
@Component
@Scope("prototype")
public class ThreadPoolTask implements Callable<String>, Serializable {
private static final long serialVersionUID = 0;
private IEmpDao empDao;
// 保存任务所需要的数据
private Object threadPoolTaskData;
private static int consumeTaskSleepTime = 2000;
public ThreadPoolTask(IEmpDao empDao) {
this.empDao = empDao;
}
public synchronized String call() throws Exception {
// 处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句
System.out.println("开始执行任务:" + threadPoolTaskData);
String result = "";
// //便于观察,等待一段时间
try {
for(int i=0;i<10;i++){
Emp emp=new Emp();
emp.setAge(i);
emp.setLoginId("test"+i);
emp.setName("测试1"+i);
emp.setNice_name("正式"+i);
empDao.create(emp);
}
result = "OK";
} catch (Exception e) {
e.printStackTrace();
result = "ERROR";
}
threadPoolTaskData = null;
return result;
}
}
public void saveEmpListAll() {
int i = 0;
String task = "task@ " + i;
System.out.println("创建任务并提交到线程池中:" + task);
FutureTask<String> futureTask = new FutureTask<String>(new ThreadPoolTask());
threadPoolTaskExecutor.execute(futureTask);
// 在这里可以做别的任何事情
String result = null;
try {
// 取得结果,同时设置超时执行时间为0.1秒。同样可以用future.get(),不设置执行超时时间取得结果
result = futureTask.get();
} 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);
}
}
org.hibernate.HibernateException: No Session found for current thread 开始执行任务:null at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106) at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014) at com.ht.dao.common.AbstractHibernateDao.getCurrentSession(AbstractHibernateDao.java:26) at com.ht.dao.common.AbstractHibernateDao.create(AbstractHibernateDao.java:43) at com.ht.service.impl.EmpService$ThreadPoolTask.call(EmpService.java:81) at com.ht.service.impl.EmpService$ThreadPoolTask.call(EmpService.java:1) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在ThreadPoolTask类中
修改如下试试
@Autowired
privateIEmpDaoempDao;
加了也是不可以的,其实这个问题的原因在于事务是绑定到线程的,事务结束session就被销毁了,所以新线程无法获得session,就是不知道如何解决。