如何避免线程中断异常
How to avoid Thread Interrupted Exception
我正在使用带线程的 Apache Lucene 为 pdf 文件编制索引。有些线程需要超过 15 分钟的时间。线程执行 15 分钟后,它会抛出 Thread interrupted Exception.Is 有一种方法可以增加时间限制来避免此问题。
当有一个线程 运行 并且它索引了将近 76% 的 pdf 文件时,我得到了这个异常。
应用服务器是 Glassfish
List<Thread> threads = new ArrayList<Thread>();
Thread worker;
for (int a = 1;a <= count; a++) {
IndexManualRunnable indexManualRunnable =
new IndexManualRunnable(indexfileLocation, collections, manual, processId);
worker = new Thread(indexManualRunnable);
worker.setName(manual.getName());
worker.setPriority(Thread.MAX_PRIORITY);
worker.start();
threads.add(worker);
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException interruptedException) {
saveReport("", "", "Interrupted Exception", 1, processId, Category.INDEXING, thread.getName());
interruptedException.printStackTrace();
}
}
更新:
我看到您正在使用 Glassfish,并且说每次 15 分钟都会发生此中断。 Glassfish 似乎设置为在大约 900 秒时超时,默认情况下为 15 分钟 - 这会引发 InterruptException。
由于您的应用程序实际需要处理超过 15 分钟,请将以下服务器配置更新为您认为合适的时间限制。
http.request-timeout-seconds
这是更新 属性 的 asadmin 命令示例,但我还没有测试它:
# asadmin set server-config.network-config.protocols.protocol.<listener-name>.http.request-timeout-seconds=-1
- NOTE: <listener-name> is the name of the listener they wish to disable the timeout on.
- (-1) means unlimited
要处理中断的线程,您可以自己捕获并处理异常。如果您希望线程继续执行,无论您理论上什么都不做 - 但为了保持代码干净和正确,我将按如下方式实现它:
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
我喜欢这个例子,因为它不只是留下一个空的 catch 子句,而是保留了它是在布尔值中调用的事实。它这样做是为了当它最终完成时您可以检查它是否被中断,如果是则尊重它并中断当前线程。
有关更多信息以及示例的来源,请查看以下文章:
http://www.ibm.com/developerworks/library/j-jtp05236/
更改 Glassfish 中的 domain.xml
<thread-pools>
<thread-pool name="http-thread-pool" idle-thread-timeout-seconds="1800" />
<thread-pool max-thread-pool-size="200" name="thread-pool-1" idle-thread-timeout-seconds="1800" />
</thread-pools>
增加空闲线程超时秒数
我正在使用带线程的 Apache Lucene 为 pdf 文件编制索引。有些线程需要超过 15 分钟的时间。线程执行 15 分钟后,它会抛出 Thread interrupted Exception.Is 有一种方法可以增加时间限制来避免此问题。
当有一个线程 运行 并且它索引了将近 76% 的 pdf 文件时,我得到了这个异常。 应用服务器是 Glassfish
List<Thread> threads = new ArrayList<Thread>();
Thread worker;
for (int a = 1;a <= count; a++) {
IndexManualRunnable indexManualRunnable =
new IndexManualRunnable(indexfileLocation, collections, manual, processId);
worker = new Thread(indexManualRunnable);
worker.setName(manual.getName());
worker.setPriority(Thread.MAX_PRIORITY);
worker.start();
threads.add(worker);
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException interruptedException) {
saveReport("", "", "Interrupted Exception", 1, processId, Category.INDEXING, thread.getName());
interruptedException.printStackTrace();
}
}
更新:
我看到您正在使用 Glassfish,并且说每次 15 分钟都会发生此中断。 Glassfish 似乎设置为在大约 900 秒时超时,默认情况下为 15 分钟 - 这会引发 InterruptException。
由于您的应用程序实际需要处理超过 15 分钟,请将以下服务器配置更新为您认为合适的时间限制。
http.request-timeout-seconds
这是更新 属性 的 asadmin 命令示例,但我还没有测试它:
# asadmin set server-config.network-config.protocols.protocol.<listener-name>.http.request-timeout-seconds=-1
- NOTE: <listener-name> is the name of the listener they wish to disable the timeout on.
- (-1) means unlimited
要处理中断的线程,您可以自己捕获并处理异常。如果您希望线程继续执行,无论您理论上什么都不做 - 但为了保持代码干净和正确,我将按如下方式实现它:
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
我喜欢这个例子,因为它不只是留下一个空的 catch 子句,而是保留了它是在布尔值中调用的事实。它这样做是为了当它最终完成时您可以检查它是否被中断,如果是则尊重它并中断当前线程。
有关更多信息以及示例的来源,请查看以下文章: http://www.ibm.com/developerworks/library/j-jtp05236/
更改 Glassfish 中的 domain.xml
<thread-pools>
<thread-pool name="http-thread-pool" idle-thread-timeout-seconds="1800" />
<thread-pool max-thread-pool-size="200" name="thread-pool-1" idle-thread-timeout-seconds="1800" />
</thread-pools>
增加空闲线程超时秒数