2013-08-21 9 views
5

Poszukuję możliwości zapętlenia na określony czas. Na przykład chciałbym wydrukować ("Cześć!") Przez 5 minut.Scala looping na określony czas

Używam Scala i Akka.

Zastanawiałem się nad wykorzystaniem przyszłości, która zakończy się za 5 minut, tymczasem użyłbym go podczas cyklu, sprawdzając, czy nie jest ona ukończona. Takie podejście nie działa dla mnie, ponieważ moja klasa nie jest aktorem i nie mogę zakończyć przyszłości z poza pętli.

Jakieś pomysły, a może są gotowe rozwiązania dla takich rzeczy?

Aktualny brzydki rozwiązanie:

def now = Calendar.getInstance.getTime.getTime 
    val ms = durationInMins * 60 * 1000 
    val finish = now + ms 

    while (now <= finish) { 
     println("hi") 
    } 

Z góry dzięki!

Odpowiedz

16

rozwiązanie @Radian jest potencjalnie niebezpieczne, ponieważ będzie ona ostatecznie zablokować wszystkie wątki w ExecutorService, gdy aplikacja działa ten kod kilka razy jednocześnie . Można lepiej użyć Deadline na to:

import scala.concurrent.duration._ 

val deadline = 5.seconds.fromNow 

while(deadline.hasTimeLeft) { 
    // ... 
} 
+0

Wygląda na to, czego szukałem, dziękuję – psisoyev

0
val timeout = future{Thread.sleep(5000)} 
while(!timeout.isCompleted){println("Hello")} 

To działa, ale nie podoba mi się to, ponieważ:

  1. długie pętle bez śpi są złe.
  2. długie pętle w głównym wątku jest blokowanie aplikacji

Innym rozwiązaniem byłoby, aby przenieść swoją logikę (funkcja drukowania) do oddzielnego aktora i przedstawić harmonogram do obsługi rozrządu dla ciebie, i inny harmonogram jednokrotnego wysłać PoisonPill po trwania

More about Scheduler

+0

Dzięki za odpowiedź. Dodałem do mojego pierwszego postu moje aktualne rozwiązanie, które jest brzydkie jak diabli. Chciałbym uniknąć pętli while, ale nie widzę możliwości. Nie chodzi o to, że pętle są złe, ale po prostu ich nie lubię. – psisoyev

+0

Proponuję użyć Harmonogramu, zaktualizowałem moją odpowiedź. – Radian

0

Można również zrobić to w sposób Aktor:

case object Init 
case object Loop 
case object Stop 

class Looper extends Actor { 
    var needToRun = true 

    def receive = { 
     case Init => 
      needToRun = true 
      self ! Loop 
     case Stop => 
      needToRun = false 
     case Loop => 
      if(needToRun) { 
       //do whatever you need to do 
       self ! Loop 
      } 
    } 
} 

A użyciu harmonogramu wysyłania wiadomości:

looperRef ! Init 
system.scheduler.scheduleOnce(5 MINUTES, looperRef, Stop) 
Powiązane problemy