指定时间后中断线程 - 问题

时间:2010-11-16 18:19:45

标签: java multithreading

我正在开发一个应用程序,其中每个 TimeMax_Sec 秒运行一个复杂的函数(优化)。该函数可能会进入循环或仅占用太多时间,并且 TimeMax_Sec 的时间由用户设置。

因此,我试图在一个单独的线程中运行该函数。要不断执行该功能,我使用命令 ScheduledExecutorService.scheduleAtFixedRate

在新线程启动之前,我必须确保现有线程不再处于活动状态并释放所有使用的资源。为此,在线程内部,我将从线程开始经过的时间与 TimeMax_Sec 进行比较,如果它更大,则线程被中断。

现在,我有两个问题:

  • 调用线程的代码看起来太复杂和多余,我想知道是否有可能使它更优雅和清晰。

代码是这样的:

public class Main {
   public static void main(String[] args) {
    Runnable threadShell = new Runnable() {

     public void run() {
      Thread thread_Object = new rtr.cicle_thread(... args ...);
      try {
        thread_Object.start();
        Thread.currentThread().sleep( timeMax_Sec*1000 );
       if ( thread_Object.isAlive() ) {
        config_Obj_Final.stopThread = true;
        System.out.println("Thread forced to stop")
        thread_Object.join();
       }
      } catch (InterruptedException e) {
       flagException();
      }
     }
    };  
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    executor.scheduleAtFixedRate(ThreadShell, 0, timeMax_Sec, TimeUnit.SECONDS);
  }
}
  • 更重要,但可能与前一个相关联,线程没有及时停止,我的印象是线程看到的时间比实际时间慢。

线程中函数代码的一个例子是:

public class cicle_thread extends Thread{
   private ... args_thread ...;

   public cicle_thread(... args ...){
    args_thread = args;
   }

   public void run(){

    Calendar threadStartTime = Calendar.getInstance();
    Calendar threadCurrentTime = Calendar.getInstance();
    long loopFrequencyMilliseconds = timeMax_Sec*1000;
    long threadLifeInMilliseconds = 0;

    threadCurrentTime = Calendar.getInstance();
    threadLifeInMilliseconds = threadCurrentTime.getTimeInMillis()-threadStartTime.getTimeInMillis();
    if(threadLifeInMilliseconds>loopFrequencyMilliseconds){
     if(Thread.currentThread().isInterrupted()){ interrupt(); return; } 
    }
    function_1();

    threadCurrentTime = Calendar.getInstance();
    threadLifeInMilliseconds = threadCurrentTime.getTimeInMillis()-threadStartTime.getTimeInMillis();
    if(threadLifeInMilliseconds>loopFrequencyMilliseconds){
     if(Thread.currentThread().isInterrupted()){ interrupt(); return; } 
    }
    function_2();

    ...

    threadCurrentTime = Calendar.getInstance();
    threadLifeInMilliseconds = threadCurrentTime.getTimeInMillis()-threadStartTime.getTimeInMillis();
    if(threadLifeInMilliseconds>loopFrequencyMilliseconds){
     if(Thread.currentThread().isInterrupted()){ interrupt(); return; } 
    }
    function_n();

}

但打印时间 ThreadLifeInMilliseconds 以及当前时间我有这个结果:

Thread_1_Start 17:12:20
Function_1 ThreadLifeInMilliseconds = 0
Function_2 ThreadLifeInMilliseconds = 31
Function_3 ThreadLifeInMilliseconds = 624
Function_4 ThreadLifeInMilliseconds = 1357
threads forced to stop

Thread_2_Start 17:12:28
Function_1 ThreadLifeInMilliseconds = 0
Function_2 ThreadLifeInMilliseconds = 47
Function_3 ThreadLifeInMilliseconds = 624
Function_4 ThreadLifeInMilliseconds = 1263
threads forced to stop

Thread_3_Start 17:12:35
Function_1 ThreadLifeInMilliseconds = 0
Function_2 ThreadLifeInMilliseconds = 16
Function_3 ThreadLifeInMilliseconds = 577
Function_4 ThreadLifeInMilliseconds = 1014
threads forced to stop
例如,在第一种情况下

,第二个线程在8秒后启动,但Function_4处的 ThreadLifeInMilliseconds 仅为1357毫秒。请注意, TimeMax_Sec 设置为3秒(3000毫秒),因此当中间线程从其睡眠状态唤醒时,它会发现子线程仍处于活动状态并写入“强制停止的线程”。

有什么想法吗?

由于

赦免,看起来代码的格式化效果不太好......

1 个答案:

答案 0 :(得分:1)

在你的工作线程(cicle_thread)中,只有当前线程被中断时才会返回:

if(ThreadLifeInMilliseconds>LoopFrequencyMilliseconds){
     if(Thread.currentThread().isInterrupted()){ interrupt(); return; } 
}

但是在你的主线程中你加入()线程,而不是中断()它:

System.out.println("Thread forced to stop")
Thread_Object.join();

因此,由于您不会中断工作线程或从工作线程中获得StopThread,它将不会返回。

要解决此问题,请在工作线程中中断线程或表示StopThread(使其成为AtomicBoolean!)。