Java并发编程实战Ⅲ

该系列文章是博主学习笔记,禁止转载,读书交流群:946541246

文章目录

  • Java并发编程实战五章学习
    • 同步容器类的问题
    • 迭代器与ConcurrentModificationException

Java并发编程实战五章学习

同步容器类的问题

public class UnsafeVectorHelpers {
    public static Object getLast(Vector list) {
        int lastIndex = list.size() - 1;
        return list.get(lastIndex);
    }

    public static void deleteLast(Vector list) {
        int lastIndex = list.size() - 1;
        list.remove(lastIndex);
    }
}

上面代码存在的问题:如果线程A在包含10个元素的Vector上调用getLast,同时线程B在同一个Vector上调用deleteLast,就会出现ArrayIndexOutOfBoundsException异常
修复:使用客户端加锁,保证是一个原子操作

public class SafeVectorHelpers {
    public static Object getLast(Vector list) {
        synchronized (list) {
            int lastIndex = list.size() - 1;
            return list.get(lastIndex);
        }
    }

    public static void deleteLast(Vector list) {
        synchronized (list) {
            int lastIndex = list.size() - 1;
            list.remove(lastIndex);
        }
    }
}

同理下面程序也会出现问题
如果有其他线程并发地修改Vector时,则可能导致麻烦。
如果在对Vector进行迭代时,另一个线程删除了一个元素,并且这两个操作交替执行,那么这种迭代方式将抛出ArrayIndexOutOfBoundsException异常

Vector vector = null;
        for (int i = 0; i < vector.size(); i++) {
            doSomething(vector.get(i));
        }

解决:

Vector vector = null;
        synchronized (vector) {
            for (int i = 0; i < vector.size(); i++) {
                doSomething(vector.get(i));
            }
        }

迭代器与ConcurrentModificationException

在for-each循环语法,对容器类进行迭代的标准方式都是使用Iterator。如果有其他线程并发地修改容器,会抛出ConcurrentModificationException异常。

List objects = Collections.synchronizedList(new ArrayList());
        // ...
        // 可能抛出ConcurrentModificationException
        for (Object o : objects) {
            //  doSomething
        }
 
  

要想避免出现ConcurrentModificationException,就必须在迭代过程中持有容器的锁
如果容器的规模很大,或者在每个元素上执行操作的时间很长,那么这些线程将长时间等待
如果不希望在迭代期间对容器加锁,那么一种替代方法就是“克隆”容器,在副本上进行迭代

toString、hashCode和equal等方法也会间接地执行迭代操作,当容器作为另一个容器的元素或键值时,就会出现这种情况。同样,containsAll、removeAll和retainAll等方法,以及把容器作为参数的构造函数,都会对容器进行迭代。所有这些间接的迭代操作都可能抛出ConcurrentModificationException

你可能感兴趣的:(Java并发编程实战)