Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Locking on a mutable object - Why is it considered a bad practice?

See this answer. It says:

Six really bad examples;

...

locking on a mutable field. e.g. synchronized(object) { object = ...; }

What's wrong with locking on a mutable field? What if object was declared as final but was not an immutable class?

like image 782
Murat Derya Özen Avatar asked Mar 08 '12 17:03

Murat Derya Özen


People also ask

Why is mutability bad?

Mutable objects reduce changeability. Mutable objects make the contracts between clients and implementers more complicated, and reduce the freedom of the client and implementer to change. In other words, using objects that are allowed to change makes the code harder to change.

Are mutable objects thread-safe?

A MessageService object is effectively immutable since its state can't change after its construction. So, it's thread-safe. Moreover, if MessageService were actually mutable, but multiple threads only have read-only access to it, it's thread-safe as well.

Why is mutability important?

Mutable objects are great to use when you need to change the size of the object, example list, dict etc.. Immutables are used when you need to ensure that the object you made will always stay the same. Immutable objects are fundamentally expensive to “change”, because doing so involves creating a copy.

What is the purpose of immutable objects?

Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.


1 Answers

It is a bad idea because if another thread changes the reference in the critical section, the threads will no longer see the same reference, and so they will not synchronize on the same object, thus running uncontrolled. Example:

 synchronized(lock1) {
     lock1 = new Object();
     sharedVariable++;
 }

Assume 2 threads are trying to enter this critical section. Thread 1 enters and thread 2 waits. Thread 1 goes in, reassigns lock1 and proceeds. Now thread 2 sees a different lock than what thread 1 acquired, which is also free, so it can also enter the critical section. Fun ensues!

If the object is final, you cannot reassign the reference to a different object, so the above problem no longer applies.

like image 60
Tudor Avatar answered Nov 15 '22 19:11

Tudor