2013-01-17 4 views
0

각 스레드가 두 개의 숫자에 대한 GCD를 계산하고 TreeMap에 숫자와 GCD를 저장하고 모든 스레드가 완료된 후에 TreeMap을 인쇄하는 다중 스레드 프로그램에서 작업하고 있습니다. 어떤 스레드가 동시에 하나의 스레드 만 데이터를 저장하는지 확인하고 어떤 스레드를 사용하여 인쇄 할 준비가되었을 때 TreeMap을 인쇄 할 수 있습니까?다중 스레드 및 Java 동기화

for (int i = 0; i < myList.size(); ++i) { 
    for (int j = i + 1; j < myList.size(); ++j) { 
     modulus1 = myList.get(i); 
     modulus2 = myList.get(j); 
     pool.execute(new ThreadProcessRunnable(modulus1, modulus2, myMap)); 
    } 
} 

public void run() { 
    ThreadProcess process = null; 
    try { 
     // Only one thread should execute the following code 
     for (Map.Entry<BigInteger, ArrayList<BigInteger>> entry : myMap.entrySet()) { 
      System.out.println("key ->" + entry.getKey() + ", value->" + entry.getValue()); 
     } 
    } catch (Exception e) { 
     System.err.println("Exception ERROR"); 
    } 
+0

[동기화] (http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html) 데이터에 액세스하는 방법 – paulsm4

+0

'for'루프 만 사용해야합니다 'if' 수표? 'List list = myMap.get (FirstModulus); if (list == null) {list = new ArrayList (); myMap.put (FirstModulus, list); } (이 경우'if (myMap.size()> 0) {...} else {...}'의 필요성을 없애고 더 쉽게 읽을 수있게 해줍니다) – pickypg

+0

이 같은 스레드 통신 토론을 봐 http://stackoverflow.com/questions/12274821/using-a-static-var-in-a-thread-as-communication-among-different-instances – pickypg

답변

0
  //Only one thread should executes the following code 
synchronize{    
for (Map.Entry<BigInteger, ArrayList<BigInteger>> entry : myMap.entrySet()) { 
       System.out.println("key ->" + entry.getKey() + ", value->" + entry.getValue()); 
      } 
} 
1

당신은 당신이지도에 단일 스레드 액세스를 보장해야 할 장소에서 syncronize(myMap) {...} 블록을 사용해야합니다.

결과를 마지막 스레드로 인쇄하는 경우 부울 플래그를 완료 신호로 사용하고 매번 검사합니다. 각 스레드가 값 변경을 볼 수 있도록하려면 volatile으로 설정하는 것을 잊지 마십시오.

UPD : Brian Goetz "Java Concurrency In Practice"는 강력하게 권장되는 읽기입니다.

+0

고마워. 부울 플래그는 각 스레드 내부에서 작동합니까? 어디서 검사해야합니까? – John

0

Collections.synchronizedMap을 사용하면 스레드로부터 안전하게 보호 할 수 있습니다. thread.join을 사용하여 모든 스레드가 종료 된 경우에만 인쇄가 완료되도록하십시오.

편집 : 메인 스레드에서 인쇄하십시오. 인쇄하기 전에 모든 스레드에서 join으로 전화하십시오.

+0

동일한 문제는 Quoi의 해결책과 관련이 있습니다. – pickypg

+0

Join은 스레드가 종료 될 때까지 대기합니다. 모든 스레드가 완료되면 어떻게 알 수 있습니까? – John