线程池工具类实现结束指定线程

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 }
View Code

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 }
View Code

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 }
View Code

3.1.移除指定线程执行截图:

技术图片

 

 3.2.移除所有任务时截图:

 

技术图片

 

 4.运行结果分析:

对于输出3.1,由于使用了异常处理,名为sub的线程睡眠被interrupted,故抛出移除,后续输出也能正常进行

对于输出3.2,由于名为mut和sub的线程都被正常处理过,sleep操作抛出异常,但结果仍然可访问,但名为add和div的线程未进行任何处理,被interrupt后call方法无返回,故get方法就会报错。

5.写在最后:

以上都是本人的测试用例,工具类存在的问题还请大神尽量多的指出,谢谢

以上是关于线程池工具类实现结束指定线程的主要内容,如果未能解决你的问题,请参考以下文章

线程池工具类几种实现

线程池

阿里年薪80W架构师2W字多线程进阶(线程池原子性并发工具类)超详细笔记

线程池

如何自定义线程池工具类(ThreadPoolUtils)

线程池的实现原理