2011-12-07 8 views
0

2つのスレッドがあり、1つはデータを挿入し、2つ目のスレッドはデータを取得します。
私は非常に奇妙な結果を得ました。スレッドセーフ環状バッファ?

スレッドセーフですか?

もしそうなら、それを修正する方法は?

これは私の循環バッファです:

private int mBufferSize; 
    private int startPointer = 0; 
    private int endPointer = 0; 
    private int bufferSize = 0; 
    private String[] buffer; 

    public BBuffer(int size) { 
     mBufferSize = size; 
     startPointer = 0; 
     endPointer = 0; 
     bufferSize = 0; 
     buffer = new String[mBufferSize]; 
    } 


    public String[] getData() { 
     String data = null; 

     if (!isEmpty()) { 
      bufferSize--; 
      startPointer = (startPointer + 1) % mBufferSize; 
      data = (String) buffer[startPointer]; 


     } else { 

      System.err.println("!"); 
      return null; 
     } 

     return data.split(","); 
    } 

    public void addData(String data) { 
     if (!isFull()) { 
      bufferSize++; 
      endPointer = (endPointer + 1) % mBufferSize; 
      buffer[endPointer] = data; 
      System.out.println("->"+data); 
     } else { 
      System.out.println("full"); 
     } 
    } 

    public boolean isEmpty() { 
     return bufferSize == 0; 
    } 

    public boolean isFull() { 
     return bufferSize == mBufferSize; 
    } 

} 
+0

これは宿題ですか?そうであれば、「宿題」でタグ付けしてください。 – melihcelik

+0

私は、addDataとgetDataを同期させるべきだと思っています。あるスレッドがaddを呼び出し、別のスレッドがgetの途中にある場合、またはその逆の場合、div演算子を使用して髪の毛の数学の途中で、悪いことが起こる可能性があります。 – user949300

答えて

0

ありません、それはスレッドセーフではありません。 getData()addData()が2つの異なるスレッドから呼び出された場合は、主にbufferSizeに両方のスレッドからアクセスされるため、問題が発生する可能性は100%です。 1つはgetData()、もう1つはaddData()です。 これを修正するには、bufferSizeメンバ変数を変更する前に、まずロックを取得する必要があります。 Thisは、スレッドやロックを開始するのに役立ちます。共有リソースを保護する方法については、こちらをご覧ください。

0

このため、基本配列を使用しているため、セマフォを使用します。 Arraylistsはスレッドセーフな方法として使用できます。しかし、あなたの実装では、バッファコールsemaphore.aquire()と終了時にsemaphore.release()を呼び出す各メソッドでセマフォを作成したい。

3

スレッドセーフではありません。

4つのメソッドの宣言に​​キーワードを追加するだけで済みます。そのようなシンプルなソリューションは、必ずしもそうとは限らないので、あなたのクラスにとってうまくいくことは幸いです。

潜在的に難しい問題の1つはString[]です。これはgetDataです。それぞれの呼び出しで新しい配列を作成するので、問題はありませんが、内部配列への参照が返された場合は同期が複雑になります。

+0

この場合、同期されたキーワードで十分である理由をもう少し説明してください。ありがとう – kenny

+1

各メソッドはオブジェクトを一貫した状態のままにします。反例は 'setFirstName'と' setLastName'メソッドを持つクラスです。両方のメソッドが同期されていても、オブジェクトが姓に対応していないファーストネームの矛盾した状態である期間があります。 – toto2

関連する問題