Java创建后台线程,它定期执行某些操作

时间:2012-07-17 10:41:37

标签: java multithreading

是否可以创建一个单独的后台线程,它可以单独执行一些操作? 我已经尝试了以下程序,但它没有像我期望的那样工作。

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秒钟”。为什么?我怎样才能创建一个后台线程,它可以独立于主线程执行某些操作?

5 个答案:

答案 0 :(得分:16)

使用java.util.TimerTaskjava.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循环中。