Now, I’m not sure whether this is a stupid question, please bear with me if it is.
Is the lock on an object ‘recursive’, i. e. if two objects have references to a third object in their fields and a thread is running a synchronized method on one of the two, can any other thread access the third object?
// a and b are some objects that implement Runnable // they both reference the same third object a.ref = c; b.ref = c; // a is run in a thread and processes some data in a loop for a long time // the method the loop belongs to is declared synchronized threadA = new Thread(a); threadA.start(); a.someSyncedMethod(); // this would block ... b.ref.someOtherSyncedMethod(); // ... but would this? a.ref.someOtherSyncedMethod(); // ... and how about this?
It’s worth separating out the concepts of ‘a lock’ and ‘locking an object’. There’s no real idea of ‘locking an object’ – there’s ‘acquiring (and releasing)’ the lock associated with an object. Yes, it sounds like I’m nitpicking – but the distinction is important because if you talk about an object being locked it sounds like no other threads will be able to change anything in the object while that lock is held.
Instead, it just means that no other thread will be able to acquire the same lock while the lock is held. There’s no direct relationship between the lock and any of the contents of the object that the lock is associated with.
Methods declared ‘synchronized’ acquire the lock associated with the instance of the object they belong to. This only makes other synchronized methods on the same object wait, and synchronized statements that explicitly sync on it.
Personally I don’t like synchronized methods – I like to make it clearer by explicitly synchronizing on a (private, final) member variable which is only used for synchronization.