2012-01-21 6 views
2

나는 대학 클래스에서 일부 PDF의 주위를 찾고 있었고, 난이 코드 부분을 발견 :동기화 된 메소드의 플래그에 액세스 하시겠습니까?

public class MyMemoryElements { 
    private String x = ""; 

    public MyMemoryElements(String message){ 
     this.x = message; 
    } 

    @Override 
    public boolean equals(Object o){ 
     if(o instanceof MyMemoryElements){ 
      MyMemoryElements tmp = (MyMemoryElements)o; 
      if(tmp.toString().equalsIgnoreCase(this.x)) 
       return true; 
      return false; 
     } 
     return false; 

    } 

    @Override 
    public String toString(){ 
     return this.x; 
    } 
} 

메인 코드 :

public class MainMemory { 
    private Vector<MyMemoryElements> storage; 
    private boolean canAccess = true; 
    private int counter = -1; 

    public MainMemory(){ 
     storage = new Vector<MyMemoryElements>(); 
    } 

    public synchronized MyMemoryElements take(String s) { 
     System.out.print("Method take has been invoked by "+s+". Element is:"); 
     while (!canAccess || storage.size()==counter+1) { 
      try { 
       wait(); 
      } catch (InterruptedException e) {} 
     } 
     canAccess = false; 
     counter++; 
     MyMemoryElements x = storage.elementAt(counter); 
     try { 
      Thread.sleep(10000); 
     } catch (InterruptedException ex) {} 
     notifyAll(); 
     System.out.println(x.toString()); 
     canAccess = true; 
     return x; 
    } 

    public synchronized void update(MyMemoryElements element) { 
     System.out.println("Producer is inserting element "+ element.toString()); 
     while (!canAccess) { 
      try { 
       wait(); 
      } catch (InterruptedException e) {} 
     } 
     canAccess = false; 
     this.storage.add(element); 
     notifyAll(); 
     canAccess = true; 
    } 
} 

내가 고려 canAccess 변수에 대한 필요성을 이해 할 수없는 것을 메서드가 동기화됩니다 (이후에notifyAll 이후가 아닌 이유).

EDIT : 추가 질문 : 이 코드에는 어떤 점이 있습니까? 나는 그것이 벡터에 뭔가를 추가하고 추가한다는 것입니다. 이러한 작업이 이미 벡터에 동기화되지 않았습니까? 이 모든 코드는 우리가 몇 장을 찍을 수 있을까요?

답변

1

동의합니다. 메서드가 동기화 된 것으로 표시되어 있으므로 이러한 추가 검사가 필요하지 않습니다. 누군가가 정말되고 싶어처럼

가 (더 동기화 문제가 없었다 정말 확인, 같습니다. :-)

아이러니하게도,이 canAccess는 스레드로부터 안전하지 않습니다 주장 할 수있다. 따라서 동기화되는 메소드가 없어도 이것이 반드시 적합한 대안이 될 수는 없습니다.

+1

나는 또한 동의한다. 우리가'synchronized'를 제거하면'canAccess'는 스레드 안전을하지 못한다. 프로그래머가'synchronized'없이 threadsafe 구현을 시도하기 시작한 것처럼 보이지만 결국'synchronized'와 오래된 코드가 아직 남아 있습니다. – havexz

+1

흠,'canAccess'를 휘발성이 아닌 다른 방법으로 (잠금, 동기화 등)이 방법을 사용하여'synchronized'하지 않고 스레드로부터 안전하게 만들 수 있습니까? 아마도 while 회 돌이에서 빠져 나와서 'canAccess = false'를 만드는 다른 쓰레드가있을 수 있다는 것을 이해합니다. 또한'notifyAll'의 순서와 플래그 변경에 관한 2 차 질문에 대한 생각은? – Bimp

+0

@ Jayto - 네,'canAccess = true'가'notifyAll()'앞에 와야합니다. 그렇지 않으면 교착 상태가 발생할 가능성이 있습니다. – ziesemer

관련 문제