1 先定义一个要调用业务的地方
/** * 线程任务类 */ class MyCallable implements Callable<Map<String, String>> { private String id; public MyCallable(String id) { this.id = id; } @Override public Map<String, String> call() throws Exception { Map<String, String> map = new HashMap<String, String>(); //业务处理部分 //处理完会返回相应的对象 return map; } }
2 定义线程池,并启动线程
public List<Map<String, String>> findDataList(String arrIds) { List<Map<String, String>> mapList = new ArrayList<Map<String, String>>(); List<FutureTask<Map<String, String>>> list = new ArrayList<>(); ExecutorService executor = new ThreadPoolExecutor(10, 10, 5000l, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); // 允许核心线程超时销毁 ((ThreadPoolExecutor)executor).allowCoreThreadTimeOut(true); //如果不设置子线程共享父线程的数据,会报这个错:No thread-bound request found: Are you referring to request attributes outside of an actual web requ //因为子线程中有使用父线程里面的session的用户信息,单起线程时如果不共享,则无法取到父线程的数据 ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); RequestContextHolder.setRequestAttributes(servletRequestAttributes,true);//设置子线程共享 if (arrIds!= null && !arrIds.equals("")) { String[] idArray = arrIds.split(","); for (String id : idArray) { MyCallable callable = new MyCallable(id); // 要执行的任务 FutureTask<Map<String, String>> futureTask = new FutureTask<Map<String, String>>(callable); executor.submit(futureTask); list.add(futureTask); } } for(FutureTask<Map<String, String>> futureTask:list) { try { mapList.add(futureTask.get()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return mapList; }
注意:一般我们使用的web项目,都是用了spring管理bean,所以这写程序的时候,尽量不要在方法中使用公共变量,比如下面的例子,如果多线程调用了下面两个方法,那么就很容易出现线程安全的问题,对于dateFormat 资源会有争抢的情况出现,具体的可以自己测试验证,我是在开发过程中踩过坑。
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
public void method1(Date date){
String datestr=dateFormat.format(date);
}
public void method2(Date date){
String datestr=dateFormat.format(date);
}