Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is volatile needed?

if I have a byte queue, where it is expected to have one thread producer, another consumer:

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; }
    // ...
}

This type of queue should not need synchronization.
readIdx is only modified by reader thread,
writeIdx only by the writer thread.

readIdx == writeIdx means, there is no content.
And the queue can only take up to buf.length-1 bytes of data.

Are the volatiles needed or can they be omitted because only one thread is the modifier of one integer state?

thx Frank

like image 977
fbenoit Avatar asked Feb 10 '23 17:02

fbenoit


1 Answers

If another thread has to read it, it needs to be volatile. The volatile keyword indicates to the JVM that the value can't be cached or have its updates reordered, otherwise updates to its value may not be visible to other threads.

The visibility concern extends to the buf array too. Since buf needs to change in step with the indexes it would seem like the write and read methods need to be synchronized. Synchronization makes the changes visible and makes sure that concurrent calls don't result in the indexes and buf contents becoming inconsistent.

like image 54
Nathan Hughes Avatar answered Feb 12 '23 07:02

Nathan Hughes