线程池工具类实现结束指定线程
Posted g177w
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池工具类实现结束指定线程相关的知识,希望对你有一定的参考价值。
1.工具类基类(配置类):ExecutorSchdule
1 public interface ExecutorSchdule { 2 3 //corePoolSize 表示允许线程池中允许同时运行的最大线程数。 4 int corePoolSize = 40; 5 6 //maximumPoolSize最大能创建多少个线程 7 int maximumPoolSize = 50; 8 9 //keepAliveTime表示线程没有任务时最多保持多久然后停止 10 long keepAliveTime = 4L; 11 12 //keepAliveTime的时间单位 13 TimeUnit unit = TimeUnit.SECONDS; 14 15 //workQueue存放超出线程池数以后的多余线程 16 BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(maximumPoolSize); 17 18 }
2.工具类实现:TaskExecutorUtil
1 /** 2 * 3 * 线程池工具类 4 * @author HUAWEI 5 * 6 */ 7 public class TaskExecutorUtil implements ExecutorSchdule { 8 9 //临时存放任务的注册表 10 private static Map<String, Future<Object>> localcache = new ConcurrentHashMap<String, Future<Object>>(); 11 12 private static ExecutorService executer = null; 13 14 private static TaskExecutorUtil executor = null; 15 16 17 //单例同步 18 public static TaskExecutorUtil getInstance(){ 19 synchronized (TaskExecutorUtil.class) { 20 if(executer == null){ 21 executer = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); 22 } 23 if(executor == null){ 24 executor = new TaskExecutorUtil(); 25 } 26 } 27 return executor; 28 } 29 30 //添加指定任务到线程池,并提交 31 public void run(Callable<Object> caller,String taskname){ 32 if(taskname==null||StringUtils.isEmpty(taskname)) 33 return; 34 Future<Object> future = executer.submit(caller); 35 localcache.put(taskname, future); 36 } 37 //移除指定线程池任务 38 public boolean removetask(String taskname){ 39 Future<Object> future = localcache.get(taskname); 40 if(future != null){ 41 future.cancel(true); 42 localcache.remove(taskname); 43 } 44 return future.isCancelled(); 45 } 46 47 //关闭线程池 48 public void shutdown(){ 49 executer.shutdown(); 50 } 51 52 //移除所有线程池任务 53 public void removealltask(){ 54 for(String taskname:localcache.keySet()){ 55 Future<Object> future = localcache.get(taskname); 56 future.cancel(true); 57 } 58 localcache.clear(); 59 } 60 61 //获取提交线程的执行结果 62 public Object get(String taskname){ 63 Object res = null; 64 Future<Object> future = localcache.get(taskname); 65 try { 66 if(future != null) 67 res = future.get(); 68 } catch (InterruptedException e) { 69 e.printStackTrace(); 70 } catch (ExecutionException e) { 71 e.printStackTrace(); 72 } 73 return res; 74 } 75 }
3.测试类:test
1 public class test { 2 /** 3 * 在每个线程池执行run()之间添加输出为了验证主线程没有被阻塞 4 * return语句不同返回为了验证返回对象的不确定性 5 * 考虑到线程可能被取消执行,这里引入执行结束正常退出操作和被Interrupt时结束正在执行的任务 6 * @param args 7 */ 8 class User{ 9 private String name; 10 public User setName(String name){ 11 this.name = name; 12 return this; 13 } 14 public String getName(){ 15 return name; 16 } 17 } 18 public static void main(String[] args) { 19 TaskExecutorUtil executor = TaskExecutorUtil.getInstance(); 20 executor.run(new Callable<Object>() { 21 22 @Override 23 public Object call() throws Exception { 24 // TODO Auto-generated method stub 25 Thread.currentThread().sleep(2*1000); 26 return 2+1; 27 } 28 }, "add"); 29 System.out.println("hihihi"); 30 executor.run(new Callable<Object>() { 31 @Override 32 public Object call() throws Exception { 33 boolean exit = false; 34 int sum = 0; 35 while(!exit&&!Thread.currentThread().isInterrupted()){ 36 try{ 37 Thread.currentThread().sleep(2*1000); 38 sum = 2-1; 39 }catch (InterruptedException e) { 40 e.printStackTrace(); 41 break; 42 } 43 } 44 return sum; 45 } 46 }, "sub"); 47 System.out.println("hihihi"); 48 executor.run(new Callable<Object>() { 49 50 @Override 51 public Object call() throws Exception { 52 // TODO Auto-generated method stub 53 boolean exit = false; 54 User user = null; 55 while(!exit&&!Thread.currentThread().isInterrupted()){ 56 try{ 57 test t = new test(); 58 Thread.currentThread().sleep(2*1000); 59 user = t.new User().setName("大圣"); 60 exit = true; 61 }catch (InterruptedException e) { 62 e.printStackTrace(); 63 break; 64 } 65 } 66 return user; 67 } 68 }, "mut"); 69 System.out.println("hihihi"); 70 executor.run(new Callable<Object>() { 71 72 @Override 73 public Object call() throws Exception { 74 // TODO Auto-generated method stub 75 Thread.currentThread().sleep(2*1000); 76 return 2/1; 77 } 78 }, "div"); 79 System.out.println("hihihi"); 80 executor.removetask("sub"); 81 // executor.removealltask(); 82 System.out.println("addoper result:"+executor.get("add")); 83 System.out.println("suboper result:"+executor.get("sub")); 84 User u = (User)executor.get("mut"); 85 System.out.println("mutoper result:"+u.getName()); 86 System.out.println("divoper result:"+executor.get("div")); 87 } 88 }
3.1.移除指定线程执行截图:
3.2.移除所有任务时截图:
4.运行结果分析:
对于输出3.1,由于使用了异常处理,名为sub的线程睡眠被interrupted,故抛出移除,后续输出也能正常进行
对于输出3.2,由于名为mut和sub的线程都被正常处理过,sleep操作抛出异常,但结果仍然可访问,但名为add和div的线程未进行任何处理,被interrupt后call方法无返回,故get方法就会报错。
5.写在最后:
以上都是本人的测试用例,工具类存在的问题还请大神尽量多的指出,谢谢
以上是关于线程池工具类实现结束指定线程的主要内容,如果未能解决你的问题,请参考以下文章