2013-08-21 8 views
5

Sto cercando una possibilità di loop per una certa durata. Ad esempio, mi piacerebbe println ("Ciao!") Per 5 minuti.Scala looping per una certa durata

Sto usando Scala e Akka.

Stavo pensando di usare il futuro, che sarà terminato in 5 minuti, nel frattempo vorrei usarlo mentre ciclo su di esso con controllo che non è completato. Tale approccio non funziona per me, dato che la mia classe non è un attore, e non posso terminare il futuro da fuori dal giro.

Qualche idea o forse ci sono soluzioni pronte per tali cose?

attuale brutta soluzione:

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

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

Grazie in anticipo!

risposta

16

la soluzione di @Radian è potenzialmente pericoloso, in quanto finirà per bloccare tutti i thread nel ExecutorService, quando la vostra applicazione gestisce questo codice più volte contemporaneamente . Si può meglio utilizzare un Deadline per questo:

import scala.concurrent.duration._ 

val deadline = 5.seconds.fromNow 

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

Sembra qualcosa che stavo cercando, grazie – psisoyev

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

Questo funziona, ma non mi piace perché:

  1. cicli a lungo senza posti letto sono cattivi.
  2. cicli lunghi nel thread principale sta bloccando l'applicazione

Un'altra soluzione, potrebbe essere quella di spostare la logica (la funzione di stampa) in un attore indipendente, e introdurre uno scheduler per gestire i tempi per voi, e un'altra scheduler-una volta per inviare un PoisonPill dopo una durata

More about Scheduler

+0

Grazie per il risposta. Ho aggiunto al mio primo post anche la mia attuale soluzione, che è brutta da morire. Mi piacerebbe evitare il ciclo, ma non vedo possibilità. Non che i loop siano cattivi, ma semplicemente non mi piacciono. – psisoyev

+0

Ti suggerisco di usare uno Scheduler, ho aggiornato la mia risposta. – Radian

0

Si può anche farlo nella maniera attore:

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 
      } 
    } 
} 

E usare scheduler per inviare un messaggio:

looperRef ! Init 
system.scheduler.scheduleOnce(5 MINUTES, looperRef, Stop)