DEV Community

loading...

Discussion on: Multithreading in Java for dummies (part 2)

Collapse
raulavila profile image
Raúl Ávila Author • Edited

Thanks for your message, you have discovered a bug in my implementation, which reveals how hard it is to work with concurrent systems.

The problem is in myTurn.awaitUninterruptibly(), as its name expresses, this method is not interruptible, so when the main class interrupts all the threads, if one of the threads is blocked due to the call to this awaitUninterruptibly method, then the thread won't wake up. This situation is not extremely likely, in fact it didn't happen to me when I implemented the example, but I was able to reproduce it after reading your message.

Debugging this kind of issues is quite hard, and it took me some time to understand what was going on. The only solution that comes to my mind at the moment is changing the call to awaitUninterruptibly to await, which receives a timeout. We can configure a long timeout if we want, but for this case 1 minute is more than enough, in fact the timeout will never happen, as the method will be interrupted:

     while(!Thread.interrupted()) {
            lock.lock();

            try {
                while (!play)
                    myTurn.await(1, TimeUnit.MINUTES);

                this.play = false;
                nextPlayer.play = true;

                nextTurn.signal();

            } catch(InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            finally {
                lock.unlock();
            }
        }
Enter fullscreen mode Exit fullscreen mode

Note that we need to catch InterruptedException and propagate the interruption to the thread, so the loop exits normally.

I hope it makes sense, and again, thanks for your message!!!