首页 > 解决方案 > 为什么 SynchronizedList 线程的这个包装器是安全的?

问题描述

我正在阅读“Java Concurrency in Practice”,这个案例对我来说有点不清楚。为什么这段代码是 ThreadSafe 的?

@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)
} }
}

我们锁定列表的实例, SynchronizedList 但在使用的内部对象内部 final Object mutex; // Object on which to synchronize

  public void add(int index, E element) {
            synchronized (mutex) {list.add(index, element);}
        }

我们仍然对两个不同的对象进行了锁定。为什么安全?

标签: javaconcurrency

解决方案


好问题。您必须遵循分配互斥锁的整个链。

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

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

mutex = this;

推荐阅读