看《java 并发编程实战》 第4章 程序清单4-14附件时

class BadListHelper <E> {

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

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

}

@ThreadSafe
class GoodListHelper <E> {

public 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;
    }
}

}

对于BadListHelper 下面的话如何理解?
clipboard.png

我的理解是:
public synchronized boolean putIfAbsent(E x)方法等同于
public boolean putIfAbsent(E x){
synchronized (this){

  ....

}
}

他是对BadListHelper 上的锁,也只能保证同一时刻只有一个线程可以访问BadListHelper 同一实例的putIfAbsent方法。但是持有list的引用的其它线程任然可以使用list其它方法修改list(即使该方法对应list来说是线程安全的、原子的); 但是我们的目的是 为了同一时刻只能有一个线程可以修改list。 因此书上说 “问题在于错误的锁上进行了同步” 。

GoodListHelper 的putIfAbsent是对list进行上锁,因此任何访问list的线程安全的方法,同一时刻只能有一个线程进行。


liumang
343 声望36 粉丝

一直在思考怎么结合自己擅长的知识做些什么。现在有了好主意坚持一年,看看会有什么改变,有什么美好的事情发生。