I was reading a threading tutorial that’s originally from (I believe) the IBM developerworks site. In it they talked about the synchronized keyword and how a synchronized block of code is locked by the actual object, not the block of code itself.
For instance, in the code below the authors state that even though the static class ‘Thingie
’s setLastAccess
method is listed as synchronized, the two threads defined below it can each call setLastAccess
simultaneously, because they’re using different values for thingie. But if thingie is static won’t that mean they’re using the same value?
Is it the case that the variable names only need be different, even if they’re referring to the same object?
public class SyncExample { public static class Thingie { private Date lastAccess; public synchronized void setLastAccess(Date date) { this.lastAccess = date; } } public static class MyThread extends Thread { private Thingie thingie; public MyThread(Thingie thingie) { this.thingie = thingie; } public void run() { thingie.setLastAccess(new Date()); } } public static void main() { Thingie thingie1 = new Thingie(), thingie2 = new Thingie(); new MyThread(thingie1).start(); new MyThread(thingie2).start(); } }
Advertisement
Answer
You are confusing a static method with a static class. If setLastAccess
was a static method then if it is marked as synchronized
, it would lock on the Class
instance in the ClassLoader
— there is only one of these per loader. If the method was static and synchronized then threads would be locking on the same object.
However, in your example the Thingie
class is marked as static, not the method. The static keyword on a class means that Thingie
is not tied to the outer SyncExample
class — it does not mean that there is only one instance of Thingie
and it does not affect synchronization. So in your example, when setLastAccess
is marked synchronized
, it is locking on the instance of the class Thingie
(this
). Since there are two instances (thingie1
and thingie2
) then the locks are on different objects. Obviously, if both threads were passed in thingie1
then they would both be locking on the same object.
Here’s some reading: