为什么 Java 线程没有收到中断标志?
Why doesn't Java Thread receive interrupt flag?
我试图了解 ExecutorService 中的中断线程,但我无法弄清楚为什么以下 MyNeverEndingRunnable class 没有获得中断信号。我有一个 class 实现了 Runnable 并且简单地打印并循环等待直到它被中断:
class MyNeverEndingRunnable
implements Runnable
{
int count = 0;
@Override
public void run()
{
while (true)
{
System.out.printf("[%d]:%d\n", Thread.currentThread().getId(), ++count);
try { Thread.sleep(5000L); } catch (Exception ignored) {}
if (Thread.interrupted())
{
break;
}
}
}
}
我生成了一些这样的线程,然后在我的 ExecutorService 上调用 shutdownNow() ,它应该在每个 运行ning 线程上调用中断,但下面的代码将永远 运行 继续:
int threadCount = 5;
ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
Future[] threads = new Future[threadCount];
for (int k = 0; k < threadCount; ++k)
{
threads[k] = executorService.submit(new MyNeverEndingRunnable());
}
Thread.sleep(20000L);
executorService.shutdownNow();
while (!executorService.isShutdown()) Thread.sleep(1000L);
有人知道我做错了什么吗?
来自Javadoc:
InterruptedException
- if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown. [My emphasis]
NB 没有任何东西可以真正保证线程被 shutdownNow()
中断。它只是将其描述为 'typical implementation'.
你的代码有点奇怪。试试这个:
try
{
Thread.sleep(5000L);
}
catch (InterruptedException exc)
{
break;
}
并删除 Thread.interrupted()
测试。
Throws:
...
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
一抛出异常,就不再中断了。在您的情况下,您可以立即跳出循环并让线程终止,正如@EJP 所建议的那样。但是,如果您的代码没有线程的所有权(例如,一个单独的方法),您需要确保将中断传播给调用者,或者通过传播异常,或者通过重新中断:
try {
while (true) {
System.out.printf("[%d]:%d\n", Thread.currentThread().getId(), ++count);
Thread.sleep(5000L);
}
} catch (InterruptedException notIgnored)
Thread.currentThread().interrupt();
}
或类似的:
while (!Thread.currentThread().isInterrupted()) {
System.out.printf("[%d]:%d\n", Thread.currentThread().getId(), ++count);
try {
Thread.sleep(5000L);
} catch (InterruptedException notIgnored)
Thread.currentThread().interrupt();
}
}
我试图了解 ExecutorService 中的中断线程,但我无法弄清楚为什么以下 MyNeverEndingRunnable class 没有获得中断信号。我有一个 class 实现了 Runnable 并且简单地打印并循环等待直到它被中断:
class MyNeverEndingRunnable
implements Runnable
{
int count = 0;
@Override
public void run()
{
while (true)
{
System.out.printf("[%d]:%d\n", Thread.currentThread().getId(), ++count);
try { Thread.sleep(5000L); } catch (Exception ignored) {}
if (Thread.interrupted())
{
break;
}
}
}
}
我生成了一些这样的线程,然后在我的 ExecutorService 上调用 shutdownNow() ,它应该在每个 运行ning 线程上调用中断,但下面的代码将永远 运行 继续:
int threadCount = 5;
ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
Future[] threads = new Future[threadCount];
for (int k = 0; k < threadCount; ++k)
{
threads[k] = executorService.submit(new MyNeverEndingRunnable());
}
Thread.sleep(20000L);
executorService.shutdownNow();
while (!executorService.isShutdown()) Thread.sleep(1000L);
有人知道我做错了什么吗?
来自Javadoc:
InterruptedException
- if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown. [My emphasis]
NB 没有任何东西可以真正保证线程被 shutdownNow()
中断。它只是将其描述为 'typical implementation'.
你的代码有点奇怪。试试这个:
try
{
Thread.sleep(5000L);
}
catch (InterruptedException exc)
{
break;
}
并删除 Thread.interrupted()
测试。
Throws: ... InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
一抛出异常,就不再中断了。在您的情况下,您可以立即跳出循环并让线程终止,正如@EJP 所建议的那样。但是,如果您的代码没有线程的所有权(例如,一个单独的方法),您需要确保将中断传播给调用者,或者通过传播异常,或者通过重新中断:
try {
while (true) {
System.out.printf("[%d]:%d\n", Thread.currentThread().getId(), ++count);
Thread.sleep(5000L);
}
} catch (InterruptedException notIgnored)
Thread.currentThread().interrupt();
}
或类似的:
while (!Thread.currentThread().isInterrupted()) {
System.out.printf("[%d]:%d\n", Thread.currentThread().getId(), ++count);
try {
Thread.sleep(5000L);
} catch (InterruptedException notIgnored)
Thread.currentThread().interrupt();
}
}