您如何java.lang.Thread
用Java 杀死A ?
ExecutorStatus
以下问题的答案:stackoverflow.com/questions/2275443/how-to-timeout-a-thread
您如何java.lang.Thread
用Java 杀死A ?
ExecutorStatus
以下问题的答案:stackoverflow.com/questions/2275443/how-to-timeout-a-thread
Answers:
有关他们为何不赞成使用Sun的内容,Thread.stop()
请参见。它详细介绍了为什么这是一个不好的方法,以及通常应该怎样做才能安全地停止线程。
他们建议的方法是使用共享变量作为标志,要求后台线程停止。然后可以由另一个请求线程终止的对象来设置此变量。
getConnection()
从java.sql.DriverManager
。如果连接attemt花费的时间太长,我尝试通过调用杀死相应的线程,Thread.interrupt()
但它根本不影响该线程。该Thread.stop()
尽管甲骨文表示,如果它不应该工作但工作,interrupt()
没有。我想知道如何使其工作并避免使用不推荐使用的方法。
在Java中,不会杀死线程,但是以协作方式完成线程的停止。要求线程终止,然后线程可以正常关闭。
通常,一个volatile boolean
字段用于该线程定期检查和终止时,它被设置到相应的值。
我不会使用a boolean
来检查线程是否应该终止。如果您使用volatile
的场调节剂,这将工作可靠,但如果你的代码变得更加复杂,对于而是使用内的其他阻止方法while
循环,它可能发生,你的代码将不会终止所有或至少需要更长的时间,你可能想要。
某些阻止库方法支持中断。
每个线程都有一个布尔标志中断状态,您应该利用它。可以这样实现:
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
源代码来自Java Concurrency in Practice。由于该cancel()
方法是公共的,因此您可以让另一个线程根据需要调用此方法。
一种方法是设置类变量并将其用作标记。
Class Outer {
public static volatile flag = true;
Outer() {
new Test().start();
}
class Test extends Thread {
public void run() {
while (Outer.flag) {
//do stuff here
}
}
}
}
设置一个外部类变量,即上例中的flag = true。将其设置为false可以“杀死”线程。
volatile
以确保它在任何地方都能正常工作。内部类不是静态的,因此标志应为实例变量。该标志应在访问器方法中清除,以便可以执行其他操作(如中断)。名称“标志”不是描述性的。
有一种方法可以做到。但是,如果您必须使用它,则说明您是一个不好的程序员,或者您正在使用一个由不好的程序员编写的代码。因此,您应该考虑停止成为一个不良的程序员或停止使用此不良代码。此解决方案仅适用于别无选择的情况。
Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
Thread.stop
即使不赞成使用,仍然可以致电公众。
Thread.stop
会执行相同的操作,但还会检查访问和权限。使用Thread.stop
是很明显的,我不记得我为什么使用它的原因Thread.stop0
。也许Thread.stop
不适用于我的特殊情况(Java 6上的Weblogic)。也许是因为Thread.stop
已弃用并引起警告。
我想根据已积累的评论添加一些意见。
Thread.stop()
如果安全管理器允许,它将停止线程。Thread.stop()
是危险的。话虽如此,如果您在JEE环境中工作并且无法控制所调用的代码,则可能有必要;请参阅为什么不赞成使用Thread.stop?stop()
ThreadDeathError
在调用线程上创建一个新错误,然后将该错误引发到目标线程上。因此,堆栈跟踪通常毫无价值。stop()
与安全管理器联系,然后stop1()
调用stop0()
。stop0()
是本机代码。Thread.stop()
开始,尚未删除,但是Thread.stop(Throwable)
在Java 11中已删除。(邮件列表,JDK-8204243)我投赞成票Thread.stop()
。
例如,您需要进行长时间的操作(例如网络请求)。假设您正在等待响应,但是这可能需要一些时间,并且用户会导航到其他UI。现在,该等待线程是a)无用的b)潜在的问题,因为当他得到结果时,它是完全无用的,并且他将触发可能导致错误数量的回调。
所有这些,他可以进行可能占用大量CPU资源的响应处理。作为开发人员,您甚至无法停止它,因为您不能if (Thread.currentThread().isInterrupted())
在所有代码中都加行。
因此无法强制停止一个奇怪的线程。
Thread.stop()
无论如何都无法安全呼叫。您不是在投票Thread.stop()
,而是在要求执行每个操作的人员,这些操作可能需要很长时间才能使其安全终止。那可能是个好主意,但与实现Thread.stop()
安全堕胎的方式无关。我们已经拥有interrupt
了。
stop
。
问题相当模糊。如果您的意思是“我该如何编写程序以使线程在需要时停止运行”,那么各种其他响应都将有所帮助。但是,如果您的意思是“我的服务器出现紧急情况,我现在无法立即重启,而我只需要一个特定的线程就死了,那就可能了”,那么您需要一个干预工具来匹配诸如的监视工具jstack
。
为此,我创建了jkillthread。请参阅其使用说明。
当然,在某些情况下,您正在运行某种不完全可信的代码。(我个人是通过允许在Java环境中执行上载的脚本来实现此目的的。是的,到处都响起了安全警报,但这是应用程序的一部分。)在这种不幸的情况下,首先,您只是希望通过请脚本编写者来实现尊重某种布尔型运行/不运行信号。唯一不错的故障保护是,如果运行时间超过某个超时时间,则在线程上调用stop方法。
但是,这仅仅是“体面的”,而不是绝对的,因为代码可能会捕获ThreadDeath错误(或您明确抛出的任何异常),而不是像绅士线程那样去抛出它。因此,最重要的是AFAIA,没有绝对的故障保护功能。
没有办法优雅地杀死线程。
您可以尝试中断线程,一种常见策略是使用毒丸向线程发送消息以使其自行停止
public class CancelSupport {
public static class CommandExecutor implements Runnable {
private BlockingQueue<String> queue;
public static final String POISON_PILL = “stopnow”;
public CommandExecutor(BlockingQueue<String> queue) {
this.queue=queue;
}
@Override
public void run() {
boolean stop=false;
while(!stop) {
try {
String command=queue.take();
if(POISON_PILL.equals(command)) {
stop=true;
} else {
// do command
System.out.println(command);
}
} catch (InterruptedException e) {
stop=true;
}
}
System.out.println(“Stopping execution”);
}
}
}
BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);
通常,您不会杀死,停止或中断线程(或检查线程是否被中断()),但应使其自然终止。
很简单。您可以在run()方法内将任何循环与(易失性)布尔变量一起使用,以控制线程的活动。您也可以从活动线程返回到主线程以停止它。
这样,您可以优雅地杀死一个线程:)。
突然终止线程的尝试是众所周知的不良编程实践,也是不良应用程序设计的证据。多线程应用程序中的所有线程都显式和隐式共享同一进程状态,并被迫相互协作以使其保持一致,否则,您的应用程序将容易出现难以诊断的错误。因此,开发人员有责任通过仔细而清晰的应用程序设计来保证这种一致性。
对于受控线程终止,有两种主要的正确解决方案:
可以在以下位置找到与突然终止线程有关的问题的详尽详尽说明,以及受控线程终止的错误和正确解决方案的示例:
我没有在Android上使用该中断,因此我使用了这种方法,效果很好:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
Thread t = new Thread(new CheckUpdates());
t.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
//Thread sleep 3 seconds
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
“杀死线程”不是正确的用法。这是我们可以按意愿实现线程的正常完成/退出的一种方法:
我使用过的Runnable:
class TaskThread implements Runnable {
boolean shouldStop;
public TaskThread(boolean shouldStop) {
this.shouldStop = shouldStop;
}
@Override
public void run() {
System.out.println("Thread has started");
while (!shouldStop) {
// do something
}
System.out.println("Thread has ended");
}
public void stop() {
shouldStop = true;
}
}
触发类:
public class ThreadStop {
public static void main(String[] args) {
System.out.println("Start");
// Start the thread
TaskThread task = new TaskThread(false);
Thread t = new Thread(task);
t.start();
// Stop the thread
task.stop();
System.out.println("End");
}
}
不推荐使用Thread.stop,那么如何在Java中停止线程?
始终使用中断方法和将来请求取消
Callable < String > callable = new Callable < String > () {
@Override
public String call() throws Exception {
String result = "";
try {
//assume below take method is blocked as no work is produced.
result = queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return result;
}
};
Future future = executor.submit(callable);
try {
String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.error("Thread timedout!");
return "";
} finally {
//this will call interrupt on queue which will abort the operation.
//if it completes before time out, it has no side effects
future.cancel(true);
}
public interface CustomCallable < T > extends Callable < T > {
void cancel();
RunnableFuture < T > newTask();
}
public class CustomExecutorPool extends ThreadPoolExecutor {
protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
if (callable instanceof CancellableTask)
return ((CancellableTask < T > ) callable).newTask();
else
return super.newTaskFor(callable);
}
}
public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
public synchronized void cancel() {
try {
obj.close();
} catch (IOException e) {
logger.error("io exception", e);
}
}
public RunnableFuture < T > newTask() {
return new FutureTask < T > (this) {
public boolean cancel(boolean mayInterruptIfRunning) {
try {
this.cancel();
} finally {
return super.cancel(mayInterruptIfRunning);
}
}
};
}
}