如何在Java中杀死Java .lang. thread ?
当前回答
“杀死一个线程”不是一个正确的短语。这里有一种方法我们可以在will上实现线程的优雅完成/退出:
我使用的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");
}
}
其他回答
线程。停止是不赞成的,所以我们如何停止一个线程在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);
}
当任务不响应中断信号时。假设任务执行套接字I/O,不响应中断信号,因此使用上述方法将不会中止任务,future将超时,但取消finally块将没有影响,线程将继续侦听套接字。如果由pool实现,我们可以关闭套接字或在连接时调用close方法。
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);
}
}
};
}
}
这里有一些关于这个主题的好读物:
如何处理InterruptedException?
干净地关闭线程
在Java中,线程不会被杀死,但是线程的停止是通过协作的方式完成的。线程被要求终止,然后线程可以优雅地关闭。
通常使用一个易失性布尔字段,线程定期检查,并在设置为相应值时终止。
我不会使用布尔值来检查线程是否应该终止。如果你使用volatile作为字段修饰符,这将可靠地工作,但如果你的代码变得更复杂,而不是在while循环中使用其他阻塞方法,它可能会发生,你的代码根本不会终止,或者至少需要更长的时间。
某些块库方法支持中断。
每个线程已经有一个布尔标志中断状态,你应该利用它。它可以这样实现:
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
源代码改编自Java并发实践。因为cancel()方法是公共的,你可以让另一个线程按你的意愿调用这个方法。
试图突然终止线程是众所周知的糟糕编程实践,也是糟糕应用程序设计的证据。多线程应用程序中的所有线程显式或隐式地共享相同的进程状态,并被迫相互协作以保持一致,否则您的应用程序将容易出现很难诊断的错误。因此,开发人员有责任通过仔细和清晰的应用程序设计来保证这种一致性。
对于受控线程终止,有两种主要的正确解决方案:
使用共享volatile标志 使用Thread.interrupt()和Thread.interrupted()方法。
关于突发线程终止相关问题的详细解释,以及受控线程终止的错误和正确解决方案的示例,可以在这里找到:
https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads
There is of course the case where you are running some kind of not-completely-trusted code. (I personally have this by allowing uploaded scripts to execute in my Java environment. Yes, there are security alarm bell ringing everywhere, but it's part of the application.) In this unfortunate instance you first of all are merely being hopeful by asking script writers to respect some kind of boolean run/don't-run signal. Your only decent fail safe is to call the stop method on the thread if, say, it runs longer than some timeout.
但是,这只是“体面的”,而不是绝对的,因为代码可以捕获ThreadDeath错误(或您显式抛出的任何异常),而不是像一个绅士线程应该做的那样重新抛出它。所以,AFAIA的底线是没有绝对的故障保险。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 自动化invokerrequired代码模式
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder