2013-03-26 2 views
1

스칼라에서 스레드를 알 수있는 방법 : 잠시만 기다려주십시오. 아니면 메시지를받을 때까지 기다려야합니까? 즉 최대 t 초 동안 휴면 상태가되지만, t가 끝나지 않고 특정 메시지를 수신하는 경우에 일어나야합니다.스칼라 : 슬리핑 웨이브

+0

IIRC, 대기 (긴 시간 초과) 과부하가 있습니까? 그렇다면, 어떤 객체를 기다리고 메시지가 사용 가능한지를 알린다. –

답변

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

하지만 임의의 깨우기 문제는 while (! messageReceived)이 아닌 if (! messageReceived)가 처리해야합니다. – user1377000

+1

당신이 선택의 여지가 없다면 (예 : 성능이 중요하고 필요한 로직이 비표준이기 때문에) 수동으로이 솔루션을 롤업하는 것은 매우 바람직하지 않습니다. 잊어 버리기가 너무 쉽습니다. 스칼라와 자바에는 더 높은 수준의 구조가 사용되어야합니다. –

+0

@ user1377000 - 임의의 깨우기는 'while'에 의해 처리되지만 시간 초과 동작은 내 제안에서 잘못된 것입니다. 각 깨우기 후에 시간 초과가 초기 값으로 다시 시작됩니다. 최악의 경우, 이것은 "영원히 대기"시나리오로 이어질 수 있습니다. – Dirk

0

주어진 시간 동안 잠자기 상태로 만들지 말고 Timeout() 메시지에서만 깨어나게 한 다음 "깨우기"를 원하면이 메시지를 중간에 보낼 수 있습니다.

3

대답은 메시지 무엇인지에 크게 의존한다. 액터 (이전 품종 또는 Akka variety)를 사용하는 경우 receive에서 시간 초과 값을 간단하게 지정할 수 있습니다. (이 메시지를 때까지 실제로 실행되지 반작용, 그래서 당신은 그것에 제한 시간을 배치 할 수 없습니다.)

// 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 원하는 경우 보낸 사람은 할 수 (이러한 상황에서 유용을 버퍼에 메시지를 패킹).