2013-08-21 54 views
5

Tôi đang tìm kiếm khả năng lặp trong một khoảng thời gian nhất định. Ví dụ, tôi muốn inln ("Xin chào!") Trong 5 phút.Vòng lặp Scala cho một khoảng thời gian nhất định

Tôi đang sử dụng Scala và Akka.

Tôi đã suy nghĩ về việc sử dụng trong tương lai, sẽ hoàn thành trong 5 phút, trong khi đó tôi sẽ sử dụng trong khi chu kỳ trên nó với kiểm tra xem nó chưa hoàn thành. Cách tiếp cận này không hiệu quả với tôi, vì lớp của tôi không phải là diễn viên, và tôi không thể hoàn thành tương lai từ bên ngoài vòng lặp.

Bất kỳ ý tưởng nào hoặc có thể có giải pháp sẵn sàng cho những thứ như vậy?

giải pháp xấu xí hiện tại:

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

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

Cảm ơn trước!

Trả lời

16

các giải pháp của @Radian là nguy hiểm, vì nó cuối cùng sẽ chặn tất cả các chủ đề trong ExecutorService, khi ứng dụng của bạn chạy mã này nhiều lần đồng thời . Bạn tốt hơn có thể sử dụng một Deadline cho rằng:

import scala.concurrent.duration._ 

val deadline = 5.seconds.fromNow 

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

Có vẻ như điều tôi đang tìm kiếm, cảm ơn bạn – psisoyev

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

này hoạt động, nhưng tôi không thích nó vì:

  1. vòng dài mà không cần ngủ là xấu.
  2. vòng dài trong Chủ đề chính được ngăn chặn ứng dụng của bạn

Một giải pháp khác, sẽ được di chuyển logic của bạn (chức năng in) vào một diễn viên riêng biệt, và giới thiệu một lịch trình để xử lý thời gian cho bạn, và khác scheduler-once để gửi một PoisonPill sau một thời gian

More about Scheduler

+0

Cảm ơn câu trả lời. Tôi đã thêm vào bài đăng đầu tiên của tôi giải pháp hiện tại của tôi là tốt, đó là xấu xí như địa ngục. Tôi muốn tránh trong khi vòng lặp, nhưng không thấy một khả năng. Không phải là trong khi vòng lặp là xấu, nhưng tôi chỉ không thích chúng. – psisoyev

+0

Tôi khuyên bạn nên sử dụng Trình lập lịch biểu, tôi đã cập nhật câu trả lời của mình. – Radian

0

Bạn cũng có thể làm điều đó theo cách diễn viên:

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

Và sử dụng lên lịch để gửi một thông điệp:

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