2013-03-04 3 views
1

두 스레드가 동시에 액세스 할 경우 매개 변수 맵이 다음 코드에서 어떻게 영향을 받는지 설명 할 수 있습니까? 동기화 된 블록 안에 있지 않기 때문에 스레드 안전성 문제에 노출되어 있습니까?동기화 된 블록 및 변수 범위

public void fun(String type, String name, Map<String, Object> parameters) { 
    parameters.put(Constants.PARM_TYPE, type); 
    parameters.put(Constants.PARM_NAME, name); 
    try { 
     synchronized (launcher) { 
      launcher.launch(type, bool, parameters); 
     } 
    } catch (Exception e) { 
     logger.error("AHHHHH, the world has ended!",e); 
    } 
} 

나는 다음과 같은 살펴 보았다하지만 난 여전히 의문을 제기하고 있습니다 : 그런 다음 같은 키를 여러 번 삽입하면 여러 스레드를 가정 Synchronized and the scope of visibility

+2

예, 맵이 스레드로부터 안전하지 않으면 모든 종류의 불량 사항이 발생할 수 있습니다. – jtahlborn

+0

필요한 것은 BlockingMap 구현입니다. – alexg

+0

@alexg 무엇이'BlockingMap'입니까? 'ConcurrentMap'을 의미 했습니까? –

답변

1

의 원인이됩니다, 다음, 더는 없다 이 코드에 문제가 있습니다.

Map parameters 이외의 메서드 매개 변수는 단지 2 String이므로 동기화 문제는 없습니다.

synchronized 블록을 메서드 수준 또는 에 넣으려면 : 서로 다른 개체입니다. 메서드를 사용하면 this에서 동기화되고, 그렇지 않으면 launcher에서 동기화됩니다. '런처'를 보호하고 싶으므로 최대한 가까운 곳에 울타리를 만들어야합니다. 따라서 launcher에서 동기화하는 것이 좋습니다.

Object lockObject = new Object()을 사용하는 다른 기술이 있는데 해당 객체에 대한 동기화를 수행하지만이 목적을 위해 과도하다고 생각하지만이를 수행 할 수 있습니다.

0

이 방법 fun()에 액세스하고,지도가 작동하는 방식입니다 해당 키의 값은 매번 재정의됩니다. 하지만 이것이 유일한 문제는 아닙니다. 경쟁 조건과 부패 문제도있을 수 있습니다. 내재적으로 안전한 스레드 데이터 구조를 원하면 HashTable이 작업을 완료한다고 가정합니다.

1

여러 스레드가 같은 parameters 인스턴스에 대한 핸들을 가지고 있고 스레드로부터 안전하지 않은 맵 구현으로이 메소드를 호출하면 모든 종류의 불량 사항이 발생할 수 있습니다 (예 : map corruption). NullPointerException 같은 예외로 나타날 수도 있습니다.

+0

구체적으로 어떤 예외가 있는지 알려주십시오. 그것은 특별한 대답이 아닙니다. – gaborsch

+0

@GaborSch - 구체적입니다. '(예 :지도 손상)' _be_ 예외도 없습니다. 이해가 안되는 답변에 투표하지 마십시오. – jtahlborn

+0

하지만 예외가있을 수 있습니다. 이러한 의미에서 'ConcurrentModificationException'조차도 발생할 수 있습니다. 그래서, 당신의 대답은 내 대답이 잘못되었습니다 - 지금까지. – gaborsch

1

공유지도가있는 경우를 상상해보십시오.

private Map<String, Object> map = new HashMap<String,Object>(); 

예를 들어 많은 스레드로 업데이트 중입니다.

new Thread(new Runnable(){ 
    public void run(){ 
     fun("a","b", map); 
    } 
}).start(); 
new Thread(new Runnable(){ 
    public void run(){ 
     fun("a","b", map); 
    } 
}).start(); 

각 스레드는 하나 개 이상의 스레드가 그 코드가 동시에 당신이 race condition있을 것이다 파라미터 맵과 같은 객체를 전달 실행하면 A Beautiful Race Condition

+1

+1 아름다운 링크를 보내 주셔서 감사합니다 :) – noMAD

0

으로 이어질 수있는 동시에지도를 업데이트 할 수 있습니다. 당신이하지 않는 한이 확실히 스레드 안전 문제가 발생할 수

:

  • 귀하의 요구 사항과지도 구현 동시 행동 (예를 들어 ConcurrentHashMap에 따라 적절한지도 구현을 사용하지만,이 실제에 많이 의존 귀하의 응용 프로그램에 대한 요구 사항)

  • 또는 스레드 안전 코드를 직접 작성하십시오 (아마도 '동기화'와 같은 동기화 프리미티브 사용).

중요 : 당신이 고려해야 할 것 같은 그냥 반드시 경쟁 조건을 제거하지 않습니다 동기화 된 블록에지도를 수정 코드의 라인을 이동하는 것을주의하시기 바랍니다하는 앱에 다른 스레드 수도 맵을 수정하고 액세스를 동기화하는 데 사용할 오브젝트를 시도하십시오. 함수의 코드는 '런처'에 대한 참조를 사용하여 동기화합니다. 당신의 parameters 인스턴스 (당신이 당신의 마지막 코멘트에 언급 한 바와 같이)별도의 경우 동기화없이 또는 '실행'과는 다른 오브젝트 동기화를 통해지도를 수정하는 다른 스레드가 경쟁 조건을