Java中的Heartbeat:timerTask还是thread.sleep()?

Ada*_*hes 5 java multithreading

我想在java中实现一个非常简单的客户端到服务器心跳.最简单的方法似乎是通过睡眠.考虑元代码的下方.

class MyClass

    Thread heartbeatThread = new Thread();

    public void() startHeartBeat{
         Thread.sleep(4000);
         sock.write("H");
      }
Run Code Online (Sandbox Code Playgroud)

这是一个适当的解决方案,还是存在我不考虑的陷阱?

我也考虑过使用这种java.util.Timer.scheduleAtFixedRate方法.这会更强大/可靠吗?如果是这样,为什么?这是一个例子(它不像IMO那样干净):

class HeartBeat
{
    Timer timer=new Timer();

    public void scheduleHeartBeat(int delay, int period) {
       timer.scheduleAtFixedRate( new HeartBeatTask(), delay, period);     
       }
}   

class HeartBeatTaskextends TimerTask {
     public void run() {
     sock.write("H");     
}
Run Code Online (Sandbox Code Playgroud)

第二种方法会被赋予更高的优先级吗?

Men*_*ena 12

首先,Thread基于你的成语不会在没有无限循环的情况下以固定的速率进行调度.

这也是一个缺点:你可能想设置一些条件来退出循环.

InterruptedException调用static时也需要捕获Thread.sleep.

计划执行的另一个流行习语是使用a ScheduledExecutorService.


找到以下3种选择:

计时器

// says "foo" every half second
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        System.out.println("foo");
    }
}, 0, 500);
Run Code Online (Sandbox Code Playgroud)
  • 优点:简单
  • 缺点:

在固定速率执行中,每次执行都是相对于初始执行的预定执行时间进行调度的.如果由于任何原因(例如垃圾收集或其他后台活动)延迟执行,则会快速连续执行两次或更多次执行以"赶上".

文档在这里.


无限循环

new Thread() {
    @Override
    public void run() {
        while (true) {
            // Says "blah" every half second
            System.out.println("blah");
            try {
                Thread.sleep(500);
            } catch (InterruptedException ie) {
                // nope
            }
        }
    }
}.start();
Run Code Online (Sandbox Code Playgroud)
  • 优点:超级简单.您可以通过编程方式改变重复延迟.
  • 缺点:Thread.sleep还是

受制于系统定时器和调度程序的精确性和准确性.......并且需要捕捉InterruptedException.

文档在这里.

也:

  • 你的无限循环可能需要(某种程度上可能很麻烦)破坏条件
  • 没有初始延迟设置,除非在无限循环之前手动应用,这将需要另一个try/ catch.

执行人

ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor();
es.scheduleAtFixedRate(
    new Runnable() {
        @Override
        public void run() {
            // Says "bar" every half second
            System.out.println("bar");
        }
    }, 
    0, 500, TimeUnit.MILLISECONDS);
Run Code Online (Sandbox Code Playgroud)
  • 优点:这是3的最新功能.非常简单和优雅 - 您也可以安排Callables(虽然不是固定费率)并重新使用ExecutorService.java.util.Timer实际提及ScheduledThreadPoolExecutor(实现ScheduledExecutorService界面)的文档是"更多功能的Timer/ TimerTask组合替代品".
  • 记录的缺点:

如果执行此任务的时间超过其周期,则后续执行可能会延迟,

文档在这里.