4

1 つのスレッド プロデューサーと別のコンシューマーがあると予想されるバイト キューがある場合:

class ByteQueue{
    byte[] buf;
    /*volatile?*/ int readIdx;
    /*volatile?*/ int writeIdx;
    Runnable writeListener;
    Runnable readListener;
    // ...
    void write( byte[] b ){
        int wr = writeIdx;
        int rd = readIdx;
        // check consistency and free space using wr+rd
        // copy to buf, starting at wr, eventually wrap around
        // update writeIdx afterwards
        writeIdx = ( wr + b.length ) % buf.length;
        // callback to notify consumer for data available
        writeListener.run();
    }
    void read( byte[] b ){
        int wr = writeIdx;
        int rd = readIdx;
        // check consistency and available data using wr+rd
        // copy buf to b, starting at rd, eventually wrap around
        // update readIdx afterwards
        readIdx = ( rd + b.length ) % buf.length;
        // callback to notify producer for free space available
        readListener.run();
    }
    int available() { return (writeIdx - readIdx) % buf.length; }
    int free() { return buf.length - available() -1; }
    // ...
}

このタイプのキューは同期を必要としません。
readIdx はリーダー スレッドによってのみ変更され、
writeIdx はライター スレッドによってのみ変更されます。

readIdx == writeIdx は、コンテンツがないことを意味します。
また、キューは最大 buf.length-1 バイトのデータしか使用できません。

1 つのスレッドだけが 1 つの整数状態の修飾子であるため、揮発性が必要ですか、または省略できますか?

thxフランク

4

3 に答える 3

2

それらを宣言する必要がありますvolatile。たとえば、 を見てみましょうreadIdx。そうでない場合volatile、書き込みスレッドの最適化は、それが変更されていないと想定し、その想定に基づいて間違った最適化を行う可能性があります。

ただし、ローカル変数(または) への割り当てのためにreadIdx、ライター スレッド (またはwriteIdxリーダー スレッド) のどこかにアクセスすることはありません。いくつかのコードが欠落しているか、そうでなければあなたの質問は本当に意味をなさないと思います.rdwr

于 2015-06-30T19:07:44.783 に答える
1

Nathan の言うとおりです。2 つのスレッドが互いの変数を上書きするということではなく、変数自体が他のスレッド (または CPU コア)から見えなくなるリスクがあるということです。

不揮発性変数を実際に使用して、CPU がより適切に作業をスケジュールできるようにする興味深いキュー、LMAX ディスラプターがあります。

于 2015-06-30T19:11:34.727 に答える