在java中,我有ExecutorService,它运行时为true,而Throwable捕获clouse。我发现线程不时会下降。这意味着系统停止功能。 所以我的问题是,首先,我怎样才能抓住“线程杀死”事件(为了在这种情况下向我发送电子邮件)? 此外,这个线程如何发生故障?
代码是:
ExecutorService changesTrackerThread = Executors.newSingleThreadExecutor();
changesTrackerThread.submit(queueUpdater());
private Runnable queueUpdater() {
return new Runnable() {
@Override
public void run() {
while (true)
{
try
{
// do some code, then sleep
Thread.sleep(2000L);
} catch (Throwable t)
{
_log.error("something bad happened, but the loop should keep running", t);
}
}
}
};
答案 0 :(得分:3)
首先,为什么你在这里使用while循环??
您应该使用scheduled executor:
ExecutorService changesTrackerThread = Executors.newSingleThreadScheduledExecutor()();
changesTrackerThread.scheduleAtFixedRate(new queueUpdater(), 0, 2, TimeUnit.SECONDS);
private Runnable queueUpdater() {
return new Runnable() {
@Override
public void run() {
try
{
// do some code
} catch (Throwable t)
{
_log.error("something bad happened", t);
}
}
};
我不知道为什么你的线程会死掉,请告诉我们完整的代码。
但是这样,即使线程死亡,Excecutor也会在给定的时间段后重新运行它(在本例中为2秒。
答案 1 :(得分:1)
正如其他人所说,您可以将while (true)
和sleep()
循环替换为ScheduledExecutorService
。在此类服务上安排重复任务将返回ScheduledFuture
,您可以使用该ScheduledExecutorService svc = Executors.newScheduledThreadPool(1);
检查此任务的状态,或者在需要时取消它。这将使您能够从代码中删除try / catch块。
像这样启动服务:
newScheduledThreadPool()
我会使用newSingleThreadScheduledExecutor()
而不是void doSomeCode() {
// do some code
}
ScheduledFuture<?> sf = svc.scheduleAtFixedRate(this::doSomeCode, 0L, 2L, TimeUnit.SECONDS);
,因为前者会在必要时重新启动线程。
然后,安排这样的工作:
doSomeCode()
(或者,如果您希望可以将ScheduledFuture
内联为lambda或匿名内部类。)
如果任务因异常而失败,会发生什么?返回的sf.get()
对象允许您以各种方式检查状态。如果你有一个可以专门用于等待失败的线程,你可以让它调用ExecutionException
,它会抛出一个ScheduledFuture.get()
来包装导致任务失败的异常。否则,它会无限期地阻止。 Future.get()
有点奇怪,与普通的sf.get()
调用不同,它永远不会返回值;它总是抛出异常。
当/如果任务失败,sf.isDone()
的调用者可以记录异常并重新提交任务,或者其他任何事情。如果您不想无限期地阻止某个主题,则可以使用sf.get(0L, TimeUnit.SECONDS)
或sf.get()
轮询失败。请注意,Throwable
的两个重载都通过抛出异常的类型传达其返回信息的全部,这可能会使它们使用起来有些不方便。
你可以在任务本身中放置异常处理,捕获ScheduledFuture
并继续,无论如何,这可能会有效。它确实将日志记录/重新启动/重新提交策略烘焙到任务本身,这可能是令人不愉快的。使用{{1}}可以将这些策略与任务执行的实际工作分开。