【问题标题】:Creating multiple timers in the same thread causes the main thread to lag在同一个线程中创建多个定时器会导致主线程滞后
【发布时间】:2019-08-28 15:00:59
【问题描述】:

我正在尝试运行一些代码,这些代码将在 100 毫秒后启用一个变量,再等待 100 毫秒然后禁用它

我尝试使用 2 个计时器,并创建一个新线程并将其休眠。这两种解决方案都会导致主线程挂起一秒钟左右。

我用于计时器的代码:

                new java.util.Timer().schedule(
                        new java.util.TimerTask() {
                            @Override
                            public void run() {
                                PlayerControl.MoveForward = false;
                            }
                        },
                        100
                );
                new java.util.Timer().schedule(
                        new java.util.TimerTask() {
                            @Override
                            public void run() {
                                PlayerControl.MoveForward = true;
                            }
                        },
                        200
                );

对于线程方法:

new Thread(() -> {
    Thread.sleep(100);
    PlayerControl.MoveForward = false;
    Thread.sleep(100);
    PlayerControl.MoveForward = true;
})

我希望这两个结果都等待 100 毫秒,将变量设置为 false,等待 100 毫秒,然后再次将其设置为 true,这对过程的其余部分没有影响。为什么会发生这种情况,我应该怎么做?

【问题讨论】:

  • 这些都不会导致主线程处理。问题出在其他地方。
  • 如果这是一个 Swing 程序,请使用 Swing Timer

标签: java multithreading timer


【解决方案1】:

在所有非守护线程都完成之前,主线程不会退出。

您可以通过以下方式使计时器线程成为守护进程:

            new java.util.Timer(true).schedule(
                    new java.util.TimerTask() {
                        @Override
                        public void run() {
                            PlayerControl.MoveForward = false;
                        }
                    },
                    100
            );

对于普通线程,你可以这样做:

Thread thread = new Thread(() -> {
    ...
});
thread.setDaemon(true);
thread.start();

【讨论】:

  • 我不确定为什么,因为主线程根本不应该退出,但这解决了它。
【解决方案2】:

就您的方法的最少修改而言,这样的事情可能会起作用:

new Thread(() -> {
    Thread.sleep(100);
    PlayerControl.MoveForward = false;
    Thread.sleep(100);
    PlayerControl.MoveForward = true;
}).start();

如果您希望它永远运行,只需执行以下操作:

new Thread(() -> {
    for(;;) {
        Thread.sleep(100);
        PlayerControl.MoveForward = false;
        Thread.sleep(100);
        PlayerControl.MoveForward = true;
    }
}).start();

如果您想限制迭代次数,只需更改for 循环中的条件即可。

您的线程方法没有改变任何东西的原因是您从未启动过线程。至于为什么你的主线程挂了,可能和你这里没有贴的代码有关。

【讨论】:

  • 我确实启动了线程,我只是忘记将那部分粘贴到我的代码块中。但是,您给出的两种解决方案仍然会导致滞后。我要试试莫里斯的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 2018-07-03
  • 2017-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多