The code is working as intended: no single thread is interfering with the output of your messages, as otherwise (if the stream wasn't synchronized internally) those letters and words would be completely mixed up and print gibberish.
However once you call wait, you put the current thread on hold and release the lock on the monitor, so other threads can print something in the meantime.
And another thing your code demonstrates very well: as timing with threads is undefined, it can happen that at the time notifyAll()
is called, one, many or zero threads are actually waiting. Which is one of the common wait/notify issues, if Thread B already called notify
before Thread A is even waiting.
In addition please note that synchronized/wait/notify is a very basic "brute force" method of thread synchronization that comes with many pitfalls and isn't very fast either as many threads are usually put on hold. It can be used for basic and simple code, but if you really want to dive into threading, you should not use it, but use the concurrent package and it's classes and features instead. The same code could for example be written using a LinkedBlockingQueue<String>
instead of using synchronized.