2017-11-15 21 views
-2

동기화 된 (new Integer (count)) 줄에서 sonar 경고가 나타납니다 대신 새 "개체"동기화.이 문제를 해결하는 방법 "대신 새"개체 "동기화"

public class PRMDataTransferHelper { 

    /** static variable to keep count */ 
    private static int count = 0; 

    private static void done() { 

     synchronized (new Integer(count)) { 
      count--; 

      if (0 == count) { 
       cleanUp(); 
      } 
     } 

     return; 
    } 

} 
+0

@MarkusFischer가 말한 것처럼,'synchronized (new )'는 기본적으로 현재 스레드에서만 존재하는 객체와 동기화되므로 (즉, \ *) 의미를 갖지 않습니다. 즉, 현재 스레드가 동시에 실행되지 않도록합니다. 정의상 어쨌든 결코 일어날 수없는 그 자체입니다. (동기화는 여전히 메모리 장벽을 의미 할 수 있지만 대개 실제 메모리 장벽이 아닙니다.) – JimmyB

+0

특수한 경우에는 [AtomicInteger'] (https://docs.oracle.com/javase/)를 참조하십시오. 7/docs/api/java/util/concurrent/atomic/AtomicInteger.html)은 사용자 측에서 추가적인 동기화가 필요없이 필요한 작업을 정확하게 수행합니다. – JimmyB

답변

2

여기에 두 가지 문제가 있습니다 : 소나 상태로

  1. 당신이이 오토 박싱에 의해 생성 될 수 있기 때문에 원시적 래퍼에 (등 즉, 정수, 롱, 부울) 동기화 안, , 그리고 소나는 이것이 위험하다는 것을 알고 있습니다. synchronized 문에 사용 된 잠금 개체가 동기화 할 모든 스레드에서 일정해야하므로 위험합니다. 프로그램 논리에서 재사용 될 수있는 모든 동적 객체는 쉽게 실패한 동기화로 이어질 수 있습니다. 따라서 Object를 인스턴스화하고 동기화에만 사용되는 특수 잠금 객체를 만드는 것이 가장 좋습니다.
  2. new Integer(count)을 사용하고 있습니다. 즉, synchronized 블록을 입력 할 때마다 새로운 정수 인스턴스가 생성됩니다. 즉, 각 스레드는 잠금 객체의 자체 버전을 볼 수 있으므로 블록은 스레드간에 전혀 동기화되지 않습니다. 동기화를 달성하려면 모든 스레드가 공유하는 잠금 객체를 다시 사용해야합니다. 정적 변수를 가진 사용자의 경우

private static Object lock=new Object(); 

등 모든 스레드가 실제로 블록의 시작 부분에 동기화되는 것을 보장 할 synchronized(lock)이 하나를 사용하여.