2017-06-03 10 views
3

次のコードは、Listへの同時アクセスでスレッドセーフですか?
volatile修飾は、ここに任意の値を追加しますか?booleanを使用して同期する

class concurrentList{ 

     private AtomicBoolean locked = new AtomicBoolean(true); 
     volatile List<Integer> list=new LinkedList<Integer>(); 
     long start = System.currentTimeMillis(); 
     long end = start + 60*100; 


     public void push(int e){ 
      while(!locked.get()); 
      list.add(e); 
      while(!locked.compareAndSet(true,false)); 
     } 

     public int pop(){ 
      int elem; 
      while(locked.get()); 
      elem=(Integer)list.remove(0); 
      while(!locked.compareAndSet(false,true)); 
      return elem; 
     } 
.... 
} 
+0

なぜ、あなたが 'push'と' pop'メソッドで異なるロック条件を持っているのか分かりません。しかし、それでは、['java.util.concurrent.Lock'](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html)を使わないでください。 ?is-external = true)オブジェクト? – n247s

答えて

2

いいえ、スレッドセーフではありません。 push()を呼び出す2つのスレッドは、完全にロックされたものを真として読み込み、リンクされたリストに同時に追加することができます。 LinkedListはスレッドセーフではないため、コードはスレッドセーフではありません。

ロックするには、AtomicBooleanではなくロックを使用します。このparticulary場合

+0

正確には、具体的かつ素早い回答のために1つプラス –

0

、Iは[this question][1]

クラスconcurrentList {Iが使用ReadWriteLockを推薦する

private AtomicBoolean locked = new AtomicBoolean(true); 
    List<Integer> list=new LinkedList<Integer>(); 
    long start = System.currentTimeMillis(); 
    long end = start + 60*100; 


    public synchronized void push(int e){ 
     while(someLock.notCondition()); //only an example 
     list.add(e); 
     someLock.notify(); 
    } 

    public synchronized int pop(){ 
     int elem; 
     while(someLock.notCondition()); 
     elem=(Integer)list.remove(0); 
     someLock.notify() 
     return elem; 
    } 
.... 
} 
+0

'someLock'とは何ですか? – saka1029

1

インこのような場合に従う方法のための同期、および変数の揮発性ではない使用します。このロックには2つの用途があります。すでにいずれかの同時について回答IEで追加するより多くの追加

class concurrentList{ 
    ReadWriteLock lock =new ReentrantReadWriteLock(); 

    private AtomicBoolean locked = new AtomicBoolean(true); 
    volatile List<Integer> list=new LinkedList<Integer>(); 
    long start = System.currentTimeMillis(); 
    long end = start + 60*100; 


    public void push(int e){ 
     lock.writeLock().lock(); 
     try{ 
      list.add(e); 
     } finally { 
      lock.writeLock().unlock(); 
     } 
    } 

    public int pop(){ 
     lock.readLock().lock(); 
     try { 
     int elem; 

     elem=(Integer)list.remove(0); 
     } finally { 
      lock.readLock().unlock(); 
     } 
     return elem; 
    } 

.... }

0

:readLockがオンのときは、無許可されている読み取り、それまでは書き込みロックはreleased.Readロックが非ブロッキングでありますAomicity可視性、またはオーダー:3つの概念をプログラミング、あなたは並行プログラムが正しく書き込まれていないスレッドセーフなプログラミング.Whenを書き込み中に考慮する必要があり、エラーは、次の3つのカテゴリのいずれかに該当する傾向があります。

アトミック性:どのアクションおよびアクションセットに分割できない影響があるかを扱います。通常、相互排除の観点から考えられます。

可視性:あるスレッドの効果を別のスレッドが見ることができるかどうかを判断します。オーダー

:1つのスレッド内のアクションはのでconcepts.You上記のすべてがロックを使用していない、それは失敗しているあなたのコードまず問題には別の

に関して順序を外れて発生することがわかるときを決定可視性と発注は保証されません。 スレッドセーフの場合は、同時APIでReadWriteLockを使用できます。またはcompareAndsetを使用する非ブロッキングリンクリストがあります。

関連する問題