1
\$\begingroup\$

I was hoping to get some feedback on what the recommended design pattern are for this subject.

public class Channel {

    private AtomicInteger buffer = new AtomicInteger(0);

    public void read() {
        // This function should keep blocking until there is something to read.

        while (buffer.get() == 0) {
            // Maybe a sleep? (Although NetBeans gives a warning for a sleep in a loop)
        }

        buffer.decrementAndGet();
    }

    public void write() {
        // This function should just write (nothing) to the buffer (by increasing the counter of the imaginary buffer).
        buffer.incrementAndGet();
    }
}

Is this safe for use in multithreading? Or is there a better approach?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

if multiple threads try to read they may each decrement the buffer if one thread was interrupted right before it could decrement and after it passed the while

Instead use a Semaphore which is designed for just this:

public class Channel {

    private Semaphore sem = new Semaphore(0);

    public void read() throws InterruptedException {
        // This function should keep blocking until there is something to read.

        sem.acquire();
    }

    public void write() {
        // This function should just write (nothing) to the buffer (by increasing the counter of the imaginary buffer).
        sem.release();
    }
}

otherwise you should decrement in a loop:

int read;
do{
    while((read = buffer.get())==0){
    //sleep
    }
}while(!buffer.compareAndSet(read, read-1));
\$\endgroup\$
3
  • \$\begingroup\$ Alright, that looks like exactly what I'm in need of. But how should I handle the InterruptedException? \$\endgroup\$
    – Tim
    Oct 2, 2014 at 12:00
  • \$\begingroup\$ You should stop the thread; it's a mechanism to aid asynchronous shutdown. Though if you never interrupt the thread then you can ignore it \$\endgroup\$ Oct 2, 2014 at 12:21
  • 1
    \$\begingroup\$ @Tim I disagree with ignoring any exception. Usually, you should simply terminate what you're doing. The simplest way is not catching the InterruptedException. This spams the whole code with throws clauses, but that's Java. Alternatively, wrap it in a RuntimeException. If you really don't want to terminate, than call Thread.currentThread().interrupt() so that it doesn't get lost. \$\endgroup\$
    – maaartinus
    Oct 2, 2014 at 12:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.