Java 单镜头背景线,避免加入?
简单的问题是,此代码是否有效,并且不会留下任何类型的资源泄漏:Java 单镜头背景线,避免加入?,java,multithreading,Java,Multithreading,简单的问题是,此代码是否有效,并且不会留下任何类型的资源泄漏: // code... final int delaySecs = 60; new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(delaySecs * 1000); // code to do
// code...
final int delaySecs = 60;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(delaySecs * 1000);
// code to do whatever delayed single-shot action
} catch (InterruptedException ex) { /* skip action */ }
}
}).start();
// more code...
如果无效,我是否应该使用像这样的Thread
子类来启用setDaemon(true)
调用:
class DaemonThread extends Thread {
public DaemonThread(Runnable target) {
super(target);
setDaemon(true);
}
}
或者别的什么?为什么不实例化
线程
,在其上调用setDaemon()
,然后通过start()
调用呢?我认为您不需要线程
子类
e、 g
最好的方法是将应该执行的任何逻辑包装到Runnable中,并将执行留给ExecutorService 如果出现以下情况,执行器将负责停止/重用线程
MyRunnable runnable = new MyRunnable();
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(runnable);
这样,您就可以将程序逻辑与执行/生命周期管理分开。执行器还能够处理线程内的异常/中断。这将允许您在不打开新线程的情况下重新启动后台逻辑。自1.5版起,Java就为您的用例提供了特定的支持,因此建议您使用它:
ScheduledExecutorService s = Executors.newScheduledThreadPool(1);
s.schedule(new Runnable() { ...my task, no Thread.sleep()... },
1, TimeUnit.MINUTES);
s.shutdown();
这样既可以实现适当的延迟,又可以在之后进行清理。是的,如果只使用一次,则更可取。我想我将从question的
类DaemonThread
中删除private
,使其更合理地抽象。+1用于消除显式睡眠。否则,我更喜欢没有临时变量的解决方案,比如这里的s
,这是否可能ScheduledExecutorService
?因为ScheduledFuture
的返回类型是ScheduledFuture
,一个允许您监视和控制计划任务进度的句柄对象,所以不可能将其变成一行。但无论如何,这是Java的标准。我通常会不假思索地提取一个方法,在本例中是一个接受可运行和时间延迟的方法。因此,目前,这看起来是我在问题中所写的最有希望的替代方法:启动包含延迟的线程,然后清理“触发并忘记”。我仍然想知道的是,如果在我的问题代码中,setDaemon(true)代码>是必需的,或者如果GC将收集未连接、未引用的线程……当然,如果睡眠时间长,不执行setDaemon
将减慢应用程序关闭,但这是另一个问题。如果没有setDaemon(true)
,并且使用显式Thread.sleep
方法,在延迟到期和任务执行之前,应用程序不会关闭。另一方面,一旦作业完成,线程就会死亡,所有内容都会被清除。Executors.newSingleThreadExecutor().execute(newrunnable(){…})代码>似乎也能工作,从文档来看,它似乎还允许实现自行决定重用线程;它不会重用线程,因为您的一行程序每次都会创建一个新的执行器,而不会关闭它。这是一个资源泄漏,与您自己的示例相反,在您的示例中,线程在其运行
方法完成时死亡。@MarkoTopolnik-Bah,所以它。。。“我想我也不接受这个答案了,很抱歉点了303号。”海德,注意下面讨论的那句诱人的一句话:。
ScheduledExecutorService s = Executors.newScheduledThreadPool(1);
s.schedule(new Runnable() { ...my task, no Thread.sleep()... },
1, TimeUnit.MINUTES);
s.shutdown();