I am learning about synchronized methods as a means of preventing race conditions and unwanted behavior in Java. I was presented with the following example, and told the race condition is quite subtle:
public class Messages { private String message = null; private int count = 2; // invariant 0 <= count && count <= 2 public synchronized void put(String message) { while( count < 2 ) this.wait(); this.message = message; this.count = 0; this.notifyAll(); } public synchronized String getMessage() { while( this.count == 2 ) this.wait(); String result = this.message; this.count += 1; this.notifyAll(); return result; } } Subtle or not, I think I have a fundamental misunderstanding of what synchronized methods do. I was under the impression they restrict access to threads through use of a lock token (or similar), and thus can never race. How, then, does this example have a race condition, if its methods are synchronized? Can anyone help clarify?