我有一个脚本,该脚本每15秒运行一次,并且每次都会创建一个新线程。有时该线程会卡住并阻塞程序的同步过程。现在,如果线程被卡住20个循环,我想杀死一个特定名称的进程。这是我的代码:
public void actionPerformed(ActionEvent e) {
Date dNow = new Date( );
SimpleDateFormat ft = new SimpleDateFormat ("dd-MM-yyyy HH:mm:ss");
System.out.println(ft.format(dNow));
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int noThreads = currentGroup.activeCount();
Thread[] lstThreads = new Thread[noThreads];
currentGroup.enumerate(lstThreads);
boolean loopthreadfound = false;
for (int i = 0; i < noThreads; i++){
try{
if (lstThreads[i].getName() == "loopthread"){loopthreadfound = true;}
}catch(Exception e1){System.out.println(e1);}
}
if (loopthreadfound == false){
loopthreadcounter = 0;
//Starten in nieuwe thread
Thread loopthread = new Thread() {
public void run() {
try {
checkonoffline();
checkDBupdates();
} catch (JSONException | SQLException | IOException e1) {
System.out.println(e1);
}
}
};
loopthread.setName("loopthread");
loopthread.start();
}else{
loopthreadcounter++;
System.out.println("Loopthread already running... counter: " + loopthreadcounter);
if (loopthreadcounter > 20){
// HERE I WANT TO KILL THE THREAD "loopthread "
}
}
}
答案 0 :(得分:0)
通常,线程名称不是唯一的。如果要将String
与Thread
关联在一起,并且该字符串标识了要停止的线程,请自己进行跟踪,而不要将其视为线程名称。
也就是说,创建一个Map<String, Thread>
。稍后,您可以通过“名称”从映射中获取正确的线程,并将其终止。
请注意,stop()
已过时。您应该找到杀死,中断或终止被阻止操作的正确方法。
答案 1 :(得分:0)
您无法杀死Java中的线程。
因此,让我们退后一步:您遇到了问题,并且认为:我知道!我会杀死线程...我该怎么做?
错误的策略。 “外部”(例如,不是从线程本身的代码内部进行)使线程结束的最常见方法是告诉线程进行自我清理。无论如何,那是...您在其中编写一些代码以便它发生的地方。
对于您的情况:大概有些I / O操作被卡住了。对于大多数I / O和大多数OS,您可以中断线程。这会导致IOException发生,从而“解贴”任何卡住的内容。我给你看一个例子。我将使用Thread.sleep
而不是I / O op,因为Java规范保证了可中断性:
在线程的代码中:
public void run() {
while (!Thread.interrupted()) {
doExpensiveOp();
try {
// sleep a long time
Thread.sleep(1000000);
} catch (InterruptedException e) {
return;
}
}
}
以及控制代码中的
Thread x = ... that thread.;
x.interrupt();
interrupt方法将“提高中断标志”,仅此而已。但是,许多Java核心库调用都与之交互。例如,如果定义为“ throw InterruptedException”的所有 ALL 方法在线程被中断时正在睡眠,则它们将立即退出,并且如果标志已启动并且您调用了这些方法之一,则不会这样做。根本不运行,它们立即退出该异常。我们还在while循环中检查标志的状态。因此,如果我们处于sleep()操作中,则如果您中断它,上述线程代码肯定会退出。如果线程当前处于其昂贵的操作部分中,则将发生以下三种情况之一:
此操作完全忽略它。当然有可能;只有声明为抛出InterruptedEx的方法才得到 GUARANTEED 的正确处理。至少在操作结束的那一刻,您的线程肯定会退出,因为睡眠调用会立即引发InterruptedEx。
此操作将处理它。例如,通过引发带有文本“ interrupted”的IOException。
操作会做一些奇怪的事情。如上面的代码片段所示,它只是代码。您可以捕获InterruptedException而什么也不做,从而清除该标志而不实际结束。 interrupt()
方法不会强制关闭或停止任何操作,Thread
上也没有方法可以强制停止它。内置代码(java.*
程序包中的东西)均不执行此类操作;他们总是忽略它,抛出InterruptedException
被指定这样做,否则抛出相关异常;几乎总是IOException
。