Java 为什么SynchronizedList的包装器是线程安全的?

Java 为什么SynchronizedList的包装器是线程安全的?,java,concurrency,Java,Concurrency,我正在阅读“实践中的Java并发”,这个案例对我来说有点不清楚。为什么这个代码是线程安全的 @ThreadSafe public class ListHelper<E> { public List<E> list = Collections.synchronizedList(new ArrayList<E>()); ... public boolean putIfAbsent(E x) { synchro

我正在阅读“实践中的Java并发”,这个案例对我来说有点不清楚。为什么这个代码是线程安全的

@ThreadSafe
public class ListHelper<E> {
    public List<E> list =
        Collections.synchronizedList(new ArrayList<E>());
    ...
    public boolean putIfAbsent(E x) {
        synchronized (list)  {
            boolean absent = !list.contains(x);
            if (absent)
} }
}

我们在两个不同的对象上仍然有锁。为什么安全?

好问题。 当分配互斥时,必须遵循整个链

如果在调用
Collections.synchronizedList
作为第二个参数时未明确指定,则它将是列表本身

在内心深处,你最终会发现:

mutex = this;

此代码在语法上无效;你有一行
if(缺席)
,后面没有一条语句。哦,我没听到。如果final
Object mutex=new Object()?如果您在创建同步列表(2 arg方法)时选择使用另一个互斥体,则需要使用该变量(互斥体)而不是列表。但是,如果您有一个类,该类内部有private
private Object mutex=new Object()是否有可能以安全的方式执行此操作?除了使用另一个额外的外部互斥锁(始终)或使用反射访问该私有字段并使用该互斥锁之外,没有。
mutex = this;