\$\begingroup\$
\$\endgroup\$
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?
1 Answer 1
\$\begingroup\$
\$\endgroup\$
3
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));
answered Oct 2, 2014 at 11:55
-
\$\begingroup\$ Alright, that looks like exactly what I'm in need of. But how should I handle the InterruptedException? \$\endgroup\$Tim– Tim2014年10月02日 12:00:33 +00:00Commented 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\$ratchet freak– ratchet freak2014年10月02日 12:21:26 +00:00Commented 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 withthrows
clauses, but that's Java. Alternatively, wrap it in aRuntimeException
. If you really don't want to terminate, than callThread.currentThread().interrupt()
so that it doesn't get lost. \$\endgroup\$maaartinus– maaartinus2014年10月02日 12:31:39 +00:00Commented Oct 2, 2014 at 12:31
lang-java