javamultithreadingsynchronize

Synchronized keyword and static classes in java


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();
    }
} 

Solution

  • 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: