我阅读了 Java 并发实践。它说这个类是线程安全的:
package net.jcip.examples;
import java.util.*;
import net.jcip.annotations.*;
/**
* ImprovedList
*
* Implementing put-if-absent using composition
*
* @author Brian Goetz and Tim Peierls
*/
@ThreadSafe
public class ImprovedList<T> implements List<T> {
private final List<T> list;
public ImprovedList(List<T> list) { this.list = list; }
public synchronized boolean putIfAbsent(T x) {
boolean contains = list.contains(x);
if (contains)
list.add(x);
return !contains;
}
// Plain vanilla delegation for List methods.
// Mutative methods must be synchronized to ensure atomicity of putIfAbsent.
public int size() {
return list.size();
}
public boolean isEmpty() {
return list.isEmpty();
}
public boolean contains(Object o) {
return list.contains(o);
}
public Iterator<T> iterator() {
return list.iterator();
}
public Object[] toArray() {
return list.toArray();
}
public <T> T[] toArray(T[] a) {
return list.toArray(a);
}
public synchronized boolean add(T e) {
return list.add(e);
}
public synchronized boolean remove(Object o) {
return list.remove(o);
}
public boolean containsAll(Collection<?> c) {
return list.containsAll(c);
}
public synchronized boolean addAll(Collection<? extends T> c) {
return list.addAll(c);
}
public synchronized boolean addAll(int index, Collection<? extends T> c) {
return list.addAll(index, c);
}
public synchronized boolean removeAll(Collection<?> c) {
return list.removeAll(c);
}
public synchronized boolean retainAll(Collection<?> c) {
return list.retainAll(c);
}
public boolean equals(Object o) {
return list.equals(o);
}
public int hashCode() {
return list.hashCode();
}
public T get(int index) {
return list.get(index);
}
public T set(int index, T element) {
return list.set(index, element);
}
public void add(int index, T element) {
list.add(index, element);
}
public T remove(int index) {
return list.remove(index);
}
public int indexOf(Object o) {
return list.indexOf(o);
}
public int lastIndexOf(Object o) {
return list.lastIndexOf(o);
}
public ListIterator<T> listIterator() {
return list.listIterator();
}
public ListIterator<T> listIterator(int index) {
return list.listIterator(index);
}
public List<T> subList(int fromIndex, int toIndex) {
return list.subList(fromIndex, toIndex);
}
public synchronized void clear() { list.clear(); }
}
我不这么认为。可以在另一个线程中引用构造函数参数 list
。所以如果这个 list
不是线程安全的,它可能在并发性上不一致。如果这个list
是线程安全的,另一个线程用list
的锁操作它,使用ImprovedList的线程用ImprovedList
的锁操作它对象锁,所以他们仍然可以同时改变它。
谁能告诉我哪里错了?
最佳答案
本书引文:
this is guaranteed to provide thread safety so long as our class holds the only outstanding reference to the underlying
List
.
所以,如果有人持有对同一列表的引用,则该类不能称为线程安全的,这是正确的。但是你不专心看书就错了。
关于java - Java Concurrency in Practice 中 ImprovedList 的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39171534/