我正在开发一个应用程序,其中每个 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毫秒),因此当中间线程从其睡眠状态唤醒时,它会发现子线程仍处于活动状态并写入“强制停止的线程”。
有什么想法吗?
由于
赦免,看起来代码的格式化效果不太好......答案 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!)。