斯卡拉:醒来睡觉的线程

时间:2013-03-26 10:41:42

标签: multithreading scala

在scala中,我如何告诉线程:睡眠t秒,或直到收到消息?即最多睡眠t秒,但如果t未结束则唤醒,并且您收到某条消息。

4 个答案:

答案 0 :(得分:3)

答案很大程度上取决于消息。如果您正在使用Actors(旧版本或Akka variety),那么您只需在接收时声明超时值。 (React在收到消息之前并没有真正运行,所以你不能对它进行超时。)

// Old style
receiveWithin(1000) {
  case msg: Message => // whatever
  case TIMEOUT =>      // Handle timeout
}

// Akka style
context.setTimeoutReceive(1 second)
def receive = {
  case msg: Message =>   // whatever
  case ReceiveTimeout => // handle timeout
}

否则,“消息”究竟是什么意思?

发送消息的一种简单方法是使用为这种事情而制作的Java并发类。例如,您可以使用java.util.concurrent.SynchronousQueue来保留消息,接收方可以调用超时的poll方法:

// Common variable
val q = new java.util.concurrent.SynchronousQueue[String]

// Waiting thread
val msg = q.poll(1000)

// Sending thread will also block until receiver is ready to take it
q.offer("salmon", 1000)

ArrayBlockingQueue在这些情况下也很有用(如果您希望发件人能够在缓冲区中打包邮件)。

答案 1 :(得分:1)

结帐Await。如果您有一些Awaitable个对象,那么这就是您所需要的。

答案 2 :(得分:1)

或者,您可以使用条件变量。

val monitor = new AnyRef
var messageReceived: Boolean = false

// The waiting thread...

def waitUntilMessageReceived(timeout: Int): Boolean = {
    monitor synchronized {
        // The time-out handling here is simplified for the purpose
        // of exhibition. The "wait" may wake up spuriously for no
        // apparent reason. So in practice, this would be more complicated,
        // actually.
        while (!messageReceived) monitor.wait(timeout * 1000L)
        messageReceived
    }
}

// The thread, which sends the message...

def sendMessage: Unit = monitor synchronized {
    messageReceived = true
    monitor.notifyAll
}

答案 3 :(得分:0)

不要让它在给定时间内休眠,只能在Timeout()msg上唤醒,然后如果你想让它“醒来”,你可以提前发送这条消息。