In Java, a synchronized method is not thread safe if it reads from and writes to one or more static member variables.
Consider:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class SomeClass { static int someCounter = 0; synchronized void doSomething() { for(int i = 0; i < 20; i++) { someCounter++; // do something that takes a bit of time, e.g. // java.net.InetAddress.getByName("www.wikipedia.org"); System.out.println("counter="+counter); } } } |
and assume the access to someCounter
is somehow thread safe because of the synchronized
keyword on doSomething
.
As soon as you call doSomething
concurrently on multiple SomeClass
instances, it will not print unique numbers. This is because the all instance share the same static member variables. Between the increment of someCounter
and printing it, its value might have already changed by another instance.
That particular bug was a bit hidden because a “SomeClass
” instance was “cached” in a JEE stateless session bean. Of course the JEE container creates multiple instances of the session bean and hence multiple instances of SomeClass
.