2013-04-13 3 views
-1

이 코드의 경우 메서드를 동기화하는 것이 좋습니까? 고마워.정적 변수에 대해 메소드를 동기화하는 것으로 충분합니까?

class{ 
    private static VariableManager = new VariableManager(); 


    ... 

    static class VariableManager{ 
     private Map<String, Integer> diffCases = new HashMap<String,Integer>(); 
     private int count=0; 

     public synchronized VariableManager get(){ 
      return this. 
     } 

     public synchronized void add(String case, Integer i){ 
      diffCases.put(case, i); 
     } 

     public synchronized void increment(){ 
      c++; 
     } 
    } 
} 

public static synchronized void process(){ 

    ... 
    variableManager.add(case, num); 
    variableManager.count(); 

} 

프로그램이 예상대로 작동하지 않으며 두 정적 변수가 어떻게 든 보호되지 않는다고 생각됩니다. 하나의 스레드를 사용하면 잘 작동합니다.

실마리가 있습니까? 고마워.

두 스레드가 동일한 이벤트 배열을 처리하고 있는데, 'eventsArray'입니다. "프로세스"방법에서는 두 변수가 synchronized 메소드에서 수정됩니다.

은 조금 더 제공한다 :

  Thread e1 = new Thread(new EventThread(eventsArray, "e1")); 
     e1.start(); 

     Thread e2 = new Thread(new EventThread(eventsArray, "e2")); 
     e2.start(); 

     e1.join(); 
     e2.join(); 
+3

예상대로 작동하지 않는 이유를 설명하십시오. 디버거를 통해 코드를 실행 해보십시오. – Kninnug

+1

다른 코드가 해당지도에 액세스하고 있습니까? 또는 카운트? 제발 그걸 게시 할 수 있니? – radai

+1

기억하십시오 : Hashtable은 동기화되지만 HashMap은 동기화되지 않습니다. – TheEwook

답변

1

는 정적 변수의 일관성을 보호하기 위해 그들에게 각 액세스는 같은 잠금 장치를 사용하여 동기화해야합니다. 변수를 읽는 것도 포함됩니다. 정적 변수가 우리에게 보여준 방법에서만 사용된다면 충분합니다. 또는 diffcases이 사용되는 다른 위치가있는 경우 동일한 모니터 (즉, 정적 변수를 묶는 클래스 개체)를 사용하여 액세스가 항상 동기화되어 있는지 확인해야합니다. 변수를 "유일한"읽는 경우에도 마찬가지입니다.

* 코드에 diffcases.add(case)이 포함되어 있습니다. 지도에 .add()을 (를) 보낼 수 없습니다. 그게 진짜 코드인가요?

스레드 안전 액세스를 부여하도록 설계된 객체에서 정적 변수를 숨겨서 동시성 인식 코드를 캡슐화하는 것을 고려하십시오. 스레드간에 정적 변수를 공유하면 종종 버그의 원인이됩니다.

+0

이를 달성하는 방법 "스레드로부터 안전한 액세스 권한을 부여하도록 설계된 객체에서 정적 변수를 숨기는 것을 고려하십시오"? – user697911

+0

방금 ​​수정되었습니다. – user697911

+0

count 및 diffCases에 대한 수정 사항이 독립적이어서 동기화 할 필요가없는 경우 (예 : 최종 일관성이 충분할 경우) ConcurrentMap 및 AtomicInteger 사용을 고려할 수 있습니다. 이러한 클래스는 여러 스레드에서 동시에 사용하도록 설계되었습니다. 만약 수정 사항이 동 기적이어야한다면 맵과 정수를 캡슐화하는 클래스를 작성하고 동기화 된 게터와 'public synchronized add (case)'와 같은 단일 수정 메소드를 제공합니다.이 메소드는 원자 적으로 맵에 넣고 카운터를 증가시킵니다. – Pyranja