死人在科特林的转变

时间:2017-05-07 12:21:05

标签: kotlin

我想在Kotlin中实现Dead man's switch。这样做是在收到最后一个TIME_INTERVALMyEvent秒发出通知。收到新的MyEvent后,它会重新启动计时器。

private val stopWatch = object : () -> Unit {
  var timer = System.currentTimeMillis()
  var isRunning = false

  override fun invoke() {
    timer = System.currentTimeMillis()
    if (isRunning) return
    synchronized(this) {
      isRunning = true

      while (System.currentTimeMillis() - timer <= TIME_INTERVAL) {}

      fireNotification()
      isRunning = false
    }
  }
}

override fun onSomeEvent(e: MyEvent?) {
  runAsync(stopWatch)
}

使用kotlin.concurrent或Java标准库是否有更简单或更简单的方法来获得此功能?

1 个答案:

答案 0 :(得分:1)

如果我理解正确的话,你的代码就是在时间间隔过去之前循环什么都不做。这是一个坏主意,因为它消耗了大量CPU无所事事,而不仅仅是等待。

我会使用ScheduledExecutr来安排通知的触发。在通知被解雇之前,我会取消返回的未来:

import java.time.Instant.now
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit

class StopWatch {
    private var future: ScheduledFuture<Void>? = null;
    private val executor = Executors.newSingleThreadScheduledExecutor()

    fun onSomeEvent() {
        synchronized(this) {
            future.let {
                future?.cancel(false)
                future = null
            }

            val command = {
                synchronized(this@StopWatch) {
                    future = null
                }
                fireNotification()
                null
            }
            future = executor.schedule(command, 2, TimeUnit.SECONDS)
        }
        println("${now()} - event")
    }

    private fun fireNotification() {
        println("${now()} - notification")
    }

    fun shutdown() {
        executor.shutdown()
    }
}

fun main(args: Array<String>) {
    val stopWatch = StopWatch()
    stopWatch.onSomeEvent()
    Thread.sleep(1000)
    stopWatch.onSomeEvent()
    Thread.sleep(1000)
    stopWatch.onSomeEvent()
    Thread.sleep(1000)
    stopWatch.onSomeEvent()
    Thread.sleep(3000)
    stopWatch.onSomeEvent()
    stopWatch.shutdown()
}

打印哪些:

2017-05-07T12:45:55.647Z - event
2017-05-07T12:45:56.741Z - event
2017-05-07T12:45:57.743Z - event
2017-05-07T12:45:58.745Z - event
2017-05-07T12:46:00.747Z - notification
2017-05-07T12:46:01.750Z - event
2017-05-07T12:46:03.753Z - notification