Locking on a mutable object - Why is it considered

2019-01-26 09:01发布

问题:

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?

回答1:

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.



回答2:

"Mutable" isn't the right word here. It's okay to lock on a mutable object, i.e. an object with state. What's wrong is to lock on a field, change it, and expect another thread to lock on the same object.



回答3:

I don't think locking a mutable object is bad in itself. It is just very hard to get it right. There are other models for concurrent processing, like actors. I suggest you look into Akka, which can be used from both Java and Scala, and is a very solid implementation.