锁定可变对象 - 为什么它被认为是一种不好的做法?

时间:2012-03-08 17:49:47

标签: java multithreading concurrency thread-safety synchronized

answer。它说:

  

六个非常糟糕的例子;

     

...

     

锁定可变字段。例如synchronized(object){object = ...; }

锁定可变字段有什么问题?如果object被声明为final但不是不可变类,该怎么办?

3 个答案:

答案 0 :(得分:14)

这是一个坏主意,因为如果另一个线程更改了临界区中的引用,则线程将不再看到相同的引用,因此它们将不会在同一对象上同步,从而不受控制地运行。例如:

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

假设2个线程正在尝试进入此关键部分。线程1进入,线程2等待。线程1进入,重新分配lock1并继续。现在,线程2看到的锁不同于线程1获取的锁,这也是免费的,因此它也可以进入临界区。随之而来的乐趣!

如果对象为final,则无法将引用重新分配给其他对象,因此上述问题不再适用。

答案 1 :(得分:5)

“Mutable”在这里不是正确的词。可以锁定可变对象,即具有状态的对象。错误的是锁定一个字段,改变它,并期望另一个线程锁定在同一个对象上。

答案 2 :(得分:1)

我认为锁定一个可变对象本身并不好。要做到这一点非常困难。还有其他并发处理模型,如演员。我建议您查看Akka,它可以在Java和Scala中使用,并且是一个非常可靠的实现。