是否可以创建一个单独的后台线程,它可以单独执行一些操作? 我已经尝试了以下程序,但它没有像我期望的那样工作。
public class Test {
private static class UpdaterThread extends Thread {
private final int TIMEOUT = 3000;
public void run() {
while (true) {
try {
Thread.sleep(TIMEOUT);
System.out.println("3 seconds passed");
} catch (InterruptedException ex) {
}
}
}
}
/**
* @param args
* the command line arguments
*/
public static void main(String[] args) {
try {
Thread u = new UpdaterThread();
u.start();
while (true) {
System.out.println("--");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
我预计每3秒“3秒钟过去”将在多个“ - ”字符串流中打印出来。 事实上,从未打印过“3秒钟”。为什么?我怎样才能创建一个后台线程,它可以独立于主线程执行某些操作?
答案 0 :(得分:16)
使用java.util.TimerTask
和java.util.Timer
:
Timer t = new Timer();
t.scheduleAtFixedRate(
new TimerTask()
{
public void run()
{
System.out.println("3 seconds passed");
}
},
0, // run first occurrence immediately
3000); // run every three seconds
答案 1 :(得分:6)
打印“3秒后通过”。移除System.out.println("--")
,您将更容易看到它们; - )
现在您还可以使用ScheduledExecutorService
,并使用Runnable
代替Thread
:
public class Test {
private static class Updater implements Runnable {
@Override
public void run() {
System.out.println("3 seconds passed");
}
}
public static void main(String[] args) throws InterruptedException {
Runnable r = new Updater();
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
service.scheduleAtFixedRate(r, 0, 3, TimeUnit.SECONDS);
Thread.sleep(10000);
service.shutdown();
}
}
答案 2 :(得分:3)
您可以使用上述方法定期运行内容,但TimerTask
可能更简单。
关于你的输出,我怀疑你的主线程不允许你的UpdaterThread
运行,因为它处于一个非常紧凑的循环中。请注意,这将取决于可用的CPU /核心等。
您是否考虑过在主主题中休息,或使用Thread.yield()?请注意该链接页面中的附带条件:
何时使用yield()?
我几乎从不说。它的行为没有标准定义 并且通常有更好的方法来执行您的任务 可能想要使用yield()执行:如果您尝试仅使用a CPU的一部分,您可以通过更可控的方式执行此操作 估计线程在其最后一块中使用了多少CPU 处理,然后睡一段时间来补偿:看 sleep()方法;
还要注意处理线程中断的this interesting article。
答案 3 :(得分:1)
我建议使用ScheduledExecutorService
。要每3秒运行UpdaterThread()
,您可以这样做:
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new UpdaterThread(), 0, 3000, TimeUnit.MILLISECONDS);
您可以在此处阅读更多内容:Java Tutorials - Executor Interfaces。
答案 4 :(得分:1)
有很多答案,但没有人说为什么他的例子不起作用。 System.out
是输出流,因此在您开始写入此流之后,JAVA将锁定它,并且所有其他线程将等待锁定应用于流。在流将解锁之后,另一个线程将能够使用此流。
要使您的示例正常工作,您应该将Thread.sleep
添加到主线程中的while
循环中。