zoukankan      html  css  js  c++  java
  • 论坛贴吧问题:如何终止运行时间超时的线程

    因为现在我要监控远程的一个方法,当这个方法执行超过一段时间时,我就要抛弃这个任务.那个方法我不能修改


    测试代码:

    public class MyThreadPool{
     
        private static MyThreadPool myThreadPool = null;
        /*** 线程的最小数*/
        private static int corePoolSize = 5;
     
        private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize*2,10,TimeUnit.SECONDS, 
                new ArrayBlockingQueue<Runnable>(corePoolSize),new ThreadPoolExecutor.AbortPolicy());
        private MyThreadPool(){}
         
         
        public static MyThreadPool getInstance(){
            if(null == myThreadPool){
                System.out.println("MyThreadPool is creating!");
                myThreadPool = new MyThreadPool();
                 
            }
            return myThreadPool;
        }
     
    /**
     * 执行任务
     */
        public void exeWork(final MyWork work,int availableTime){
             
            FutureTask<Boolean> future = new FutureTask<Boolean>(new Callable<Boolean>(){
                public Boolean call(){
                    return work.doSometing();
                }
                 
            });
            executor.execute(future);
            try{
                future.get(availableTime, TimeUnit.SECONDS);
            }catch(ExecutionException e1){
                e1.printStackTrace();
                 
            }catch(InterruptedException e2){
                e2.printStackTrace();
            }catch(TimeoutException e3){
                System.out.println("执行任务超时!");
            }finally{
                future.cancel(true);
                closeExecutor();
            }
        }
         
        public void closeExecutor(){
            if(executor != null && executor.getActiveCount() ==0 && executor.getQueue().isEmpty()){
                executor.shutdown();
            }
        }
         
         
        public static int getCorePoolSize() {
            return corePoolSize;
        }
     
        public static void setCorePoolSize(int corePoolSize) {
            MyThreadPool.corePoolSize = corePoolSize;
        }
         
         
    }
    

    Main 方法

    public static void main(String[] args){
             
            MyThreadPool threadPool = MyThreadPool.getInstance();
            int availableTime = 5;
                     
            MyWork b = new BWork();
            threadPool.exeWork(b, availableTime);
    
    public class BWork implements MyWork{
        public boolean doSometing(){
             
            System.out.println("B starting...");
                    //模拟远程的方法 最坏的情况是死循环
            while(true){
                 
             
            }
             
        }
    }
    

      

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

     回答:

    1 worker 最好以以下的形式进行循环

    while (true) {
        if (Thread.currentThread().isInterrupted()) {
            return;
        }
        // do something
     
        // thread sleep 
     
    }
    

    这样打断该线程,以便结束该线程的生命周期。
    其实executor.shutdown和shutdownnow也是调用thread.interupte来结束线程池的生命周期的

     // shutdownnow
       for (Worker w : workers) {
            w.interruptNow();
       }
       // shutdown
       for (Worker w : workers) {
            w.interruptIfIdle();
       }
    

    2 其实最简单的方法是设置所创建的thread为守护线程就可以了。
    thread factory 生成thread的时候设置t.setDaemon(true);

    //  t.setDaemon(true);
    private static ThreadPoolExecutor executor = new ThreadPoolExecutor(
                corePoolSize, corePoolSize * 2, 10, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(corePoolSize),
                new ThreadFactory() {
                    public Thread newThread(Runnable r) {
                        // TODO Auto-generated method stub
                        final Thread t = new Thread(r);
                        t.setDaemon(true);
                        threads.add(t);
     
                        return t;
                    }
                }, new ThreadPoolExecutor.AbortPolicy());
    

    以下是全部代码

    package test.thread.csdn;
     
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.ThreadFactory;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
     
    public class InterupteThreadTest {
     
       private static InterupteThreadTest myThreadPool = null;
       private static int corePoolSize = 5;
       private static final List<Thread> threads = new ArrayList<Thread>();
     
       private static ThreadPoolExecutor executor = new ThreadPoolExecutor(
             corePoolSize, corePoolSize * 2, 10, TimeUnit.SECONDS,
             new ArrayBlockingQueue<Runnable>(corePoolSize),
             new ThreadFactory() {
                public Thread newThread(Runnable r) {
                   // TODO Auto-generated method stub
                   final Thread t = new Thread(r);
                   t.setDaemon(true);
                   threads.add(t);
     
                   return t;
                }
             }, new ThreadPoolExecutor.AbortPolicy());
     
       private InterupteThreadTest() {
       }
     
       public static InterupteThreadTest getInstance() {
          if (null == myThreadPool) {
             System.out.println("MyThreadPool is creating!");
             myThreadPool = new InterupteThreadTest();
          }
          return myThreadPool;
       }
     
       /**
        * exeWork
        */
       public void exeWork(int availableTime) {
          FutureTask<Boolean> future = new FutureTask<Boolean>(
                new Callable<Boolean>() {
                   public Boolean call() {
                      // dead loop mock
                      while (true) {
                         try {
                            Thread.sleep(500);
                         } catch (InterruptedException e) {
                            e.printStackTrace();
                         }
                      }
                   }
                });
          executor.execute(future);
     
          try {
             System.out.println(future.get(availableTime, TimeUnit.SECONDS));
          } catch (ExecutionException e1) {
             e1.printStackTrace();
          } catch (InterruptedException e2) {
             e2.printStackTrace();
          } catch (TimeoutException e3) {
             System.out.println("timeout!");
          }
       }
     
       public void shut() {
          executor.shutdown();
       }
     
       /**
        * @param args
        * @throws InterruptedException
        */
       public static void main(String[] args) throws InterruptedException {
          final InterupteThreadTest instance = InterupteThreadTest.getInstance();
          instance.exeWork(4);
          instance.shut();
       }
    }
    

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    回复:

    1 worker 最好以以下的形式进行循环

    while (true) {
        if (Thread.currentThread().isInterrupted()) {
            return;
        }
        // do something
    }
    

    首先感谢你的回帖,但是有几点前提我需要澄清:
    首先 我为什么把 work.doSomething() 抽象来 就是因为 那是我即将调用别人的方法,我没办法改,我要做的就是判断 doSomething 这个方法是否已经超时,如果超了 那就结束(或抛出)这个线程。
    另外main 方法不应该提供对操作池的操作 因为是开放给其他人用的。
    还有 我在网上找了几天资料,说线程 是没办法被 kill 的 那 tomcat又是如何做到抛出超时连接的呢?

  • 相关阅读:
    excel提取一类具有相似结构的部分数据,2种方式;数据——分列——分割符号/固定宽度;
    excel文字随单元格大小变化
    python操作excel
    Docker容器使用
    阿里云服务器部署好后,浏览器远程访问,提示无法访问此网站;
    StringBuffer和StringBuilder的区别
    【Linux运维-集群技术进阶】集群/分布式环境下5种session处理策略
    mysql如何进行以,分割的字符串的拆分
    Dubbox的介绍和简单示例
    JAVA回调机制(CallBack)详解
  • 原文地址:https://www.cnblogs.com/yuyu666/p/10069381.html
Copyright © 2011-2022 走看看