2017-05-07 4 views
1

Kotlin에 Dead man's switch을 구현하고 싶습니다. 이는 마지막으로 MyEvent을받은 후 TIME_INTERVAL 초 후에 알림을 발생시킵니다. 새로운 MyEvent이 수신되면 타이머가 다시 시작됩니다. Kotlin의 죽은 사람의 스위치

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

정확하게 이해하면 코드는 루핑을 수행하여 시간 간격이 경과 할 때까지 아무것도 수행하지 않습니다. 이것은 단지 기다리는 것이 아니라 많은 것을하는 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([email protected]) { 
        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 
+0

감사합니다! 빈 루프는 예제에 불과합니다. 나는 쉽게 잘 수있다. 예 : 'while (System.currentTimeMillis() - timer <= 2000) {Thread.sleep (Math.abs (2000 - (System.currentTimeMillis() - timer))}'. 또한'private var future : ScheduledFuture ? = null;'나는 오히려 피해야 할 패턴입니다. – breandan