It's because you're casting to char
which doesn't allow nulls. Also, don't do sharedQueue.isEmpty()
followed by peek
- that is known as "check-then-act" which is a well-known cause of races.
You should define sharedQueue
as BlockingQueue<Character>
then use
if ((Character c = sharedQueue.poll()) != null)