2013-07-22 3 views
1

소켓을 통해 클라이언트와 통신하는 Java 서버 응용 프로그램이 있습니다. 모든 클라이언트 요청은 새 스레드에서 처리됩니다. 하지만 일부 요청의 경우 두 클라이언트를 동기화해야합니다.다른 스레드에서 특정 신호를 얻을 때까지 스레드 차단 (java)

:

  • 클라이언트 A는 S에서 서버 S.
  • 스레드 S1에 요청을 전송은 S1이 (GoogleCloudMessaging 통해)이 요청에 대해 클라이언트 B에 통지 A.
  • 의 요청을 받아 들인다.
  • S1 지금
  • 클라이언트 B가 S로부터 정보를 수신하고, S.에 요청을 전송 차단해야
  • S에
  • 스레드 S2는
  • S1 지금 풀어에서 메시지가되어야
  • B.의 요청을 수락 S2
  • S1은

내가 잠금 상태 메커니즘에 대해 알고 클라이언트에 대한 답을 보내지 만, 스레드를 생성 할 때 나는 상태를 알 수 없기 때문에이 여기에 작동하지 않습니다. 다음과 같은 것이 필요합니다.

// Pseudo Code 
// on the S1 Thread, first argument beeing a signal ID, second a timeout 
s1.waitForSignal("clientB", 10000); 
// and on the S2 Thread to continue S1 
SignalSender.send("clientB"); 

Java에서 가능한 것은 무엇입니까? 내 문제에 대한 다른 해결책이 있습니까?

+0

예, 대기 및 알림 방법이 있습니다. 그들을 사용해보십시오. – Ankit

+3

아니요, * 대기 및 알림 *을 사용하지 마십시오. 그것들은 과거의 유물이며 새로운 코드는 그것을 사용해서는 안됩니다. 'CountDownLatch'와 같은'java.util.concurrent'의 적절한 동기화 보조 도구를 사용하십시오. –

+0

고마워, 피자 예를 좋아해. 하지만 wait & notify를 사용하면 두 스레드 모두에서 대기중인 객체의 인스턴스가 필요합니다. 그렇습니까? 왜냐하면 어떤 스레드가 생성시에 어떤 스레드를 기다리거나 알리는 지 모르기 때문입니다. 소켓에서 메시지를 파싱 할 때 (또는 SSLSession 객체를 가져올 때)이를 처음 알 수 있습니다. – user2564801

답변

0

귀하의 문제는 당신이/notifywait가 (당신이 사용할 수있는 공유 잠금 상태를 언급하지 않기 위하여) 호출 할 수있는 공유 된 기준이없는 것 같다.

글쎄, 우선 이미 두 스레드간에 공유 물건이있다 : 즉, 귀하의 경우, 문자열 "ClientB". 이 작업을 수행하는 경우 두 문자열 모두에서 액세스 할 수있는 위치의 단일 참조로 해당 문자열을 매핑하면됩니다.

간단한 구현 어딘가에 정적지도 필드를 개최 그냥 어떻게 든 모니터 개체를 채우기 위해 다음과 같습니다

public final class Monitors { 

    private Monitors() {} 

    private static final Map<String, Object> monitors = new HashMap<String, Object>(); 

    static { monitors.put("ClientB", new Object()); } 

    public static Object get(String key) { return monitors.get(key); } 

} 

물론, 당신은이 매핑 아마도 사용을 관리하는 적절한 서비스를 작성 할 수 있습니다 내부적으로 잠금 장치 및 조건. 또한 서비스 자체 내에 대기 및 신호 기능을 캡슐화 한 후 다음과 같이 사용하는 것이 좋습니다. monitorService.waitForSignalsFrom("ClientB").

+0

귀하의 답변은 실제로 OP가 생각한 바를 정확하게 설명 한 것이 었습니다. :) –

+0

사실 : 나는 해결책을 지적했다; 실제 구현은 사용하기에 너무 단순합니다. 하지만 당신 말이 맞아요, 결국 그 종류의 경고가 나옵니다. 나는 편집 할 것입니다. –

+0

방금 ​​힘든 시간을 보냈습니다. 이 문제에 대한 아주 깨끗한 해결책이있는 것 같지 않습니다 (SO 답변에서 대답 할 수 있음). –