2012-01-21 3 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'で終了しました。古いコードはまだそこにあります。 – havexz

+1

ええ、おそらく 'canAccess'をvolatileにする以外に、このアプローチ(ロックや同期などはありません)を使って' synchronized'なしでスレッドセーフなものにするのはどうでしょうか?おそらくwhileループを終了し、 'canAccess = false'とすると、同じことをする別のスレッドが存在する可能性があります。 - また、 'notifyAll'の順序に関する二次質問の考え方とフラグの変更は? – Bimp

+0

@Jayto - はい、 'canAccess = true'は' notifyAll() 'の前に来なければなりません。そうしないとデッドロックの可能性があるようです。 – ziesemer

関連する問題