Collections.synchronizedList and synchronized

前端 未结 6 1976
星月不相逢
星月不相逢 2020-11-27 11:36
List list = Collections.synchronizedList(new ArrayList());
synchronized (list) {
    list.add(\"message\");
}

Is the bl

6条回答
  •  悲&欢浪女
    2020-11-27 12:11

    Like what has been mentioned by others, the synchronized collections are thread-safe, but the compound actions to these collections are not guaranteed to be thread-safe by default.

    According to JCIP, the common compound actions can be

    • iteration
    • navigation
    • put-if-absent
    • check-then-act

    The OP's synchronized code block isn't a compound action, so no difference whether add it or not.

    Let's take the example from JCIP and modify it a little to clarify why it's necessary to guard the compound actions with lock.

    There are two methods that operate on same collection list that wrapped by Collections.synchronizedList

    public Object getLast(List list){
        int lastIndex = list.size() - 1;
        return list.get(lastIndex);
    }
    
    public void deleteLast(List list){
        int lastIndex = list.size() - 1;
        list.remove(lastIndex);
    }
    

    If methods getLast and deleteLast are called at the same time by two different threads, below interleaves may happen and getLast will throw ArrayIndexOutOfBoundsException. Assume current lastIndex is 10.

    Thread A (deleteLast) --> remove
    Thread B (getLast) --------------------> get

    The Thread A remove the element before the get operation in Thread B. Thus, the Thread B still use 10 as the lastIndex to call list.get method, it will lead to concurrent problem.

提交回复
热议问题