在一个线程里执行一个长时间的任务,比如数据库操作,我想在设定的时间内如果还没有执行完,立刻中止该线程。
以下是我的测试代码,在指定的时间内并未结束线程,线程一直在运行着,请大家看看怎么实现这个功能,谢谢!
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class InterruptedThread {        /**
         * @param args
         */
        public static void main(String[] args) {
                final MyThread myTh = new MyThread();
                         
                  final Timer t = new Timer(200,new ActionListener(){
                      public void actionPerformed(ActionEvent e) {
                          System.out.println("1 actionPerformed:"  );
                          myTh.interrupt();
                         
                      }
                  });
                  t.setRepeats(false);                  t.start();
                  myTh.start();
         }}class MyThread extends Thread {
        public void run() {
            for(int i=0;i<100000000;i++){
                System.out.println("MyThread run:" + i);
            }
            
         }
}

解决方案 »

  1.   

    我以前也遇到过这个问题,我的解决方案是:在当前这个线程上(操作时间比较久的代码)新启动一个“守护线程”,再将守护线程执行后sleep一段时间(这个时间你来定),如果守护线程发现父线程还在执行,就将父线程关闭掉,就OK了,具体代码实现你自己写吧,实在写不出来可以给我发邮件,我再告诉你具体写法。
    [email protected]
      

  2.   

    我把代码贴出来吧,共同讨论:入口函数:
    public class TestThread { /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    FatherThread father = new FatherThread();
    father.start();
    }}
    父线程:
    public class FatherThread extends Thread{
    public void run(){
    try{
    System.out.println("开始监听此代码段,给两秒钟执行时间:");
       
    ListenThread thread = new ListenThread(2*1000,this);//监听2秒
    thread.start();
    //写死循环进行测试
    boolean flag = true;
    while(flag){

    }
    //以下这句是不会打出来的,因为当前的线程被守护线程关闭了
    System.out.println("监听完毕,未发现代码执行有问题,所以取消监听器");
    thread.cancel(); 


    }catch(Exception e){
    e.printStackTrace();
    }
    }
    }守护线程:public class ListenThread extends Thread{
    private boolean isCanceled = false;
    private FatherThread fatherThread = null;
     /**
      * 计时器超时时间
      */
    private long timeout;
    /**
      * 构造器
      * @param timeout 指定超时的时间
      */
     public ListenThread(long timeout,FatherThread father) {
      super();
      this.fatherThread = father;
      this.timeout = timeout;
      //设置本线程为守护线程
      this.setDaemon(true);
     }
     /**
      * 取消计时
      */
     public void cancel()
     {
      isCanceled = true;
     }
     /**
      * 启动超时计时器
      */
     public void run()
     {
      try {
    //log.info("线程开始睡觉:"+timeout+"毫秒。");
    System.out.println("父线程状态:"+this.fatherThread.isAlive()+"");
        Thread.sleep(timeout);
        if(!isCanceled){
           //只要是在指定的timeout时间内,被监控的代码段没有执行完,则中止该线程
         System.out.println("关闭父线程");
       //System.out.println("父线程状态:"+this.fatherThread.isAlive()+"");
       //if(this.fatherThread.isAlive()){
       //System.out.println("父线程还活着,需要关闭");
       this.fatherThread.stop();  
       //System.out.println("父线程状态:"+this.fatherThread.isAlive()+"");
       //}
        }else System.out.println("不需要关闭父线程");
      } catch (Exception e) {
      System.out.println("守护线程异常");
      e.printStackTrace();
      }   
     }
    }
      

  3.   

    我理解,应该是个多线程的问题。
    其中涉及到两个线程,一个是任务线程,一个是监控线程。
    首先要明确各个线程的功能,内容。
      1.任务线程要具备两个功能,一个功能是执行任务(就是LZ所说的长时间任务);另一个功能应该是终止正在进行的任务。
      2.终止正在进行的任务,这个功能,一般是通过在代码中设置标志位来处理的。
         设置一个boolean型的变量作为标志位(线程运行是设置为true,结束时设置为false),找出任务的每个原子操作
         (一般原子操作的时间会非常短,如果有长时间的原子操作或原子操作有阻塞操作,同时又不允许长时间等待关闭,则该方案不推荐使用),
         在执行每个原子操作之前,先判断标志位,如果标志位为false则终止任务(当然,可以同时记录日志)。
      3.监控线程,由于LZ的要求是要在某个时间点到达时,再判断并终止任务线程,所以,代码可以上来先sleep到时间点,
         然后,在判断任务线程的标志位,如果为true,就设置成false,这样,任务线程,会自动终止。
    其次要明确步骤。
      1.任务线程在开始任务之前要设置标志位为true,同时创建监控线程(一般会将本身传递给监控线程的构造器)并运行监控线程。
      2.任务线程开始执行任务,同时监控线程会进入sleep
      3.当监控线程结束sleep后,会判断任务线程是否正在执行(判断标志位),如果为true就将其设置为false。
    最后,补充一点,对标志位的更改操作,一般封装在任务线程的某个方法里面,让监控线程去调用。
      

  4.   


    关于停止父线程的,这个问题,我考虑了很久,stop()在JDK中是不建议使用的,的确存在问题。不知道你使用这个方法的环境如何,是否是考虑到了其他因素对stop()后,对父线程的影响。希望能给出使用stop()是否安全可行的思路