java 多线程学习-----初入线程池
使用线程池初衷
最近项目做代码优化,有一业务功能,大致描述为有20几台分机往总机发送文件,总机在收到文件之后,会往分机反馈数据处理情况。
这时候想到使用调度来查询总机收到的消息,处理之后分别发送至各分机,为避免排队处理,决定使用多线程,并使用线程池来管理。
创建线程池
查找资料之后,采用JDK1.5的java.util.concurrent包创建线程池,本例使用可重用固定线程数的线程池,代码如下:
private static int maxThreads = 20;//最大线程数private static ExecutorService e = Executors.newFixedThreadPool(maxThreads);//创建一个有固定数量线程的线程池
FutureTask<Boolean> ft = new FutureTask<Boolean>(thread,true);e.execute(ft);Boolean fTaskResult = ft.get(); //不设置等待时间,等待计算完成,获取结果//Boolean fTaskResult = ft.get(fTimeout, TimeUnit.SECONDS); //设置等待时间,时间到了之后,获取任务执行结果,如果超时,则会抛出TimeoutException异常
catch (TimeoutException e) {System.out.println("主线程等待计算结果超时,因此中断任务线程");ft.cancel(true);}
/** * 执行任务 * @param t线程对象 */public static void beginTask(Thread t){e.execute(t);}/** * 不设置超时时间的任务调用 * @param key线程标识 * @param t线程对象 */public static void beginTask(String key,Thread thread){final String fKey = key;final FutureTask<Boolean> ft = new FutureTask<Boolean>(thread,true);runningTaskMap.put(key, ft);//存储任务标识e.execute(ft);beginTask(new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubtry {Boolean fTaskResult = ft.get();if(fTaskResult){System.out.println("key为:"+fKey+"的线程执行完成");}} catch (InterruptedException e) {System.out.println("主线程在等待计算结果时被中断");} catch (ExecutionException e) {System.out.println("主线程等待计算结果,但计算抛出异常");}finally{runningTaskMap.remove(fKey);//移除线程标识}}});}
//创建一个带有标识的任务集合private static Map<String, FutureTask<Boolean>> runningTaskMap = Collections.synchronizedMap(new HashMap<String, FutureTask<Boolean>>());
/** * 根据传入的任务标识,来中断对应任务 * @param key任务标识 */public static void intteruptTask(String key){FutureTask<Boolean> ft = runningTaskMap.get(key);ft.cancel(true);if(ft.isDone()){runningTaskMap.remove(key);}}
package task.concurrent.threadPoor;import java.util.Collections;import java.util.HashMap;import java.util.Map;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.FutureTask;import java.util.concurrent.TimeUnit;import java.util.concurrent.TimeoutException;public class FixedThreadPool {private static int maxThreads = 20;//最大线程数private static ExecutorService e = Executors.newFixedThreadPool(maxThreads);//创建一个有固定数量线程的线程池//创建一个带有标识的任务集合private static Map<String, FutureTask<Boolean>> runningTaskMap = Collections.synchronizedMap(new HashMap<String, FutureTask<Boolean>>());/** * 执行任务 * @param t线程对象 */public static void beginTask(Thread t){e.execute(t);}/** * 不设置超时时间的任务调用 * @param key线程标识 * @param t线程对象 */public static void beginTask(String key,Thread thread){final String fKey = key;final FutureTask<Boolean> ft = new FutureTask<Boolean>(thread,true);runningTaskMap.put(key, ft);//存储任务标识e.execute(ft);beginTask(new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubtry {Boolean fTaskResult = ft.get();if(fTaskResult){System.out.println("key为:"+fKey+"的线程执行完成");}} catch (InterruptedException e) {System.out.println("主线程在等待计算结果时被中断");} catch (ExecutionException e) {System.out.println("主线程等待计算结果,但计算抛出异常");}finally{runningTaskMap.remove(fKey);//移除线程标识}}});}/** * 设置有超时时间的任务调用 * @param key线程标识 * @param thread线程对象 * @param timeout秒 */public static void beginTask(String key, Thread thread, int timeout) {final String fKey = key;final int fTimeout = timeout;final FutureTask<Boolean> ft = new FutureTask<Boolean>(thread,true);runningTaskMap.put(key, ft);//存储任务标识e.execute(ft);beginTask(new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubtry {Boolean fTaskResult = ft.get(fTimeout, TimeUnit.SECONDS);if(fTaskResult){System.out.println("key为:"+fKey+"的线程执行完成");}} catch (InterruptedException e) {System.out.println("主线程在等待计算结果时被中断");} catch (ExecutionException e) {System.out.println("主线程等待计算结果,但计算抛出异常");} catch (TimeoutException e) {System.out.println("主线程等待计算结果超时,因此中断任务线程");ft.cancel(true);}finally{runningTaskMap.remove(fKey);//移除线程标识}}});}/** * 根据传入的任务标识,来中断对应任务 * @param key任务标识 */public static void intteruptTask(String key){FutureTask<Boolean> ft = runningTaskMap.get(key);ft.cancel(true);if(ft.isDone()){runningTaskMap.remove(key);}}/** * 关闭线程池 */public static void shutDownPool(){e.shutdown();}}