Toni Kanoni
Toni Kanoni

Reputation: 2317

Does a static lock object need to be final when using a synchronized(lock object) block?

Assume I have a

private static Object lock = new Object();

and somewhere in the same class

public void run() {
synchronized(lock) {
    //only 1 thread here, all others wait
  }
}

I always read that the lock object should be final, but not exactly why. Assume I know for 100% that my code doesn't touch the lock object anywhere, if one omits the final keyword, does this mean that the synchronization is not 100% bulletproof?

Upvotes: 2

Views: 605

Answers (2)

Nathan Hughes
Nathan Hughes

Reputation: 96434

Without the final modifier you are relying on however the object was initialized to make it properly visible, and assuming that nothing changes its value. Since it is static then the initialization occurs when the class is loaded and there are visibility guarantees, so technically you can get away with leaving it non-final. (Although the code uses a synchronized block the lock being used has to be evaluated before the block is entered of course.)

If the lock object is changed for another one while it is in use, then two threads can be in the same section of protected code, and the whole locking scheme is compromised. Adding the final keyword here would mean the compiler is helping you make sure this lock doesn’t change, and will result in a compile error if someone later tries to change it.

It’s generally a good thing to get as much help as you can from the compiler, and a compile will show you whether the field is changed or not, so it is a low risk change to make that makes sure a big problem can’t happen.

Upvotes: 3

Davide Lorenzo MARINO
Davide Lorenzo MARINO

Reputation: 26946

Using the final in this context is only a good practice.

You can synchronize using any object, final or non final, static or non static.

Using together final and static will give you the security that nobody will synchronize the same code on a different lock. Without using the final you are not sure that somewhere in the code that variable is not reassigned.

Generally speaking using final for a variable that is never reassigned after inited it's a good programming practice. It improves readability because who reads your code knows that this variable will never been reassigned also without reading the full code.

Upvotes: 5

Related Questions