gpt4 book ai didi

java - 客户端加锁是否违反了同步策略的封装?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:34:10 27 4
gpt4 key购买 nike

Java_author 所述,

Client-side locking entails guarding client code that uses some object X with the lock, X uses to guard its own state.


下面代码中的对象 X 是 list。上面说了,使用ListHelper类型对象拥有的锁来同步putIfAbsent(),是错误的锁。

package compositeobjects;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ListHelper<E> {

private List<E> list =
Collections.synchronizedList(new ArrayList<E>());


public boolean putIfAbsent(E x) {
synchronized(list){
boolean absent = !list.contains(x);
if(absent) {
list.add(x);
}
return absent;
}
}
}

但是,Java 作者说,

Client-side locking has a lot in common with class extension—they both couple the behavior of the derived class to the implementation of the base class. Just as extension violates encapsulation of implementation [EJ Item 14], client-side locking violates encapsulation of synchronization policy.

我的理解是,Collections.synchronizedList() 返回的嵌套类实例,也使用了 list 对象拥有的锁。


为什么在 ListHelper 中使用客户端锁定(使用 list)违反了同步策略的封装?

最佳答案

您依赖于 synchronizedList 使用自身作为监视器这一事实,目前恰好是这样。

你甚至依赖于 synchronizedList 使用 synchronized 来实现同步,这在目前也恰好是真的(这是一个合理的 假设,但这不是必要的)。

有一些方法可以更改 synchronizedList 的实现,从而导致您的代码无法正常工作。


例如,the constructor of synchronizedList :

SynchronizedList(List<E> list) {
super(list);
// ...
}

可以改成

SynchronizedList(List<E> list) {
super(list, new Object());
// ...
}

现在,SynchronizedList 实现中的方法使用的 mutex 字段不再是 this(有效),因此在 上进行外部同步code>list 将不再有效。


话虽如此Javadoc 中描述了使用synchronized (list) 确实具有预期效果的事实。 ,所以这种行为不会被改变,所以你现在所做的是绝对没问题的;它是使用泄漏抽象设计的,因此如果您从头开始做类似的事情,则不应设计成这样,但记录了泄漏抽象的属性。

关于java - 客户端加锁是否违反了同步策略的封装?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46704446/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com