Java 中断休眠线程
试图中断一个正在运行的线程,在本例中为t1,该线程由线程池中的线程执行 t2是发送中断的那个 我无法停止运行的t1,t1没有得到InterruptedException 我错过了什么Java 中断休眠线程,java,multithreading,interrupt,Java,Multithreading,Interrupt,试图中断一个正在运行的线程,在本例中为t1,该线程由线程池中的线程执行 t2是发送中断的那个 我无法停止运行的t1,t1没有得到InterruptedException 我错过了什么 Executor exec1 = Executors.newFixedThreadPool(1); // task to be interrupted Runnable runnable = new Runnable() { @Override public
Executor exec1 = Executors.newFixedThreadPool(1);
// task to be interrupted
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.out.println("starting uninterruptible task 1");
Thread.sleep(4000);
System.out.println("stopping uninterruptible task 1");
} catch (InterruptedException e) {
assertFalse("This line should never be reached.", true);
e.printStackTrace();
}
}
};
final Thread t1 = new Thread(runnable);
// task to send interrupt
Runnable runnable2 = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
t1.interrupt();
System.out.println("task 2 - Trying to stop task 1");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread(runnable2);
exec1.execute(t1);
t2.start();
t2.join();
要中断执行器线程
final ExecutorService exec1 = Executors.newFixedThreadPool(1);
final Future<?> f = exec1.submit(runnable);
...
f.cancel(true);
final ExecutorService exec1=Executors.newFixedThreadPool(1);
最终未来f=exec1.submit(可运行);
...
f、 取消(真);
调用Thread.interrupt不一定会引发InterruptedException。它可能只是设置线程的中断状态,可以由thread.interrupted()或thread.isInterrupted轮询
有关更多详细信息,请参见()。似乎您误解了线程和执行器。您为两个可运行程序创建了两个threads对象,但只启动其中一个(t2),即传递给Executor在其中运行的t1。但执行器不需要提供线程——它只需要可运行的实现。Executor本身是一个线程池(通常,但不是必需的),它只是在其中创建(和池)线程。它将线程视为简单的可运行线程(即线程实现)。因此,您实际上向从未启动的线程发送中断
若你们真的想让你们的代码工作,你们应该删除Executor,只需要显式地启动两个线程 您的错误是试图在
线程池上执行线程
这似乎是可行的,因为线程
碰巧实现了可运行
,但因为该线程仅用作可运行
,而不是作为线程
启动,调用中断()等方法将不会产生预期效果
如果您仍然需要使用线程池,那么应该考虑使用类似FutureTask
的类。将Runnable
包装到FutureTask
中,然后将任务提交到线程池。然后,当您想中断任务时,调用futureTask.cancel(true)
问题是您永远无法真正知道执行器将使用哪个线程运行任务
即使您提交了线程
对象,执行器也将使用由固定线程池创建的线程。因此,引用为t1
的线程不是执行任务的线程。因此调用t1.interrupt()
不会有任何作用
正确的方法是使用ExecutorService
并使用submit()
提交Runnable
/Callable
对象。这将返回一个Future
,它公开了一个cancel()
方法,可用于取消任务 问题是Runnable
现在将执行两次:一次通过线程池,一次通过线程t1
final Future f=exec1.submit(Runnable);f、 取消(真)代码>你错了,请仔细阅读文档。。如果被中断的线程正在睡眠…如果被中断的线程正在睡眠。。。这就是我的意思,当线程被中断时,可能线程没有休眠。谢谢BegemoT。这是有道理的。