JAVA与数据结构

2018-04-22  本文已影响7人  靈08_1024

本文地址:https://www.jianshu.com/p/df5440c30a3b


容器类的线程安全比较

ArrayList(不安全)-->Vector(线程安全,基于方法的synchronized,性能一般)-->CopyOnWriteArrayList(线程安全,基于全局ReentrantLock,性能良好,容易内存溢出,不能实时,适合读多写少,保证最终一致性);

HashMap(不安全)-->HashTable(线程安全,基于方法的synchronized)-->ConcurrentHashMap(线程安全);

HashSet(不安全)--> CopyOnWriteArraySet(线程安全,底层CopyOnWriteArrayList);
TreeSet(不安全)-->ConcurrentSkipListSet(线程安全);
TreeMap(不安全)--> ConcurrentSkipListMap(线程安全);

所有的Collections.synchronizedXXX(new XXX())都是基于对象的synchronized。
ConcurrentHashMap JDK7/8的区别:https://www.jianshu.com/p/c0642afe03e0
JDK7中,ConcurrentHashMap比HashMap安全是因为使用了分段锁segment,而segment继承了ReentrantLock。
JDK8中,ConcurrentHashMap和HashMap数据结构一样,其安全的原因是使用了CAS。

修改异常错误

在遍历时,需要对list进行操作(比如删除),删除完后list就短了,后面的遍历次数也就少了。在本次操作之前,我知道有java.util.ConcurrentModificationException这个异常的存在,也知道需要用迭代器来操作。但这次竟然有卡在这儿了,因为涉及到递归迭代。

//递归创建菜单子节点
    private void getchildMenu(List<MenuResource> list, MenuResource parent, VineTree vineTree) {
        Iterator iterator = list.iterator();
        while(iterator.hasNext()) {
            MenuResource menu = (MenuResource) iterator.next();
            if (parent.getId().equals(menu.getPid())) {
                 VineTree  vineTree1 = new VineTree(menu.getId().toString(), menu.getNameMenu());
                vineTree.addOne2Child(vineTree1);
                iterator.remove();
                List list1 = new ArrayList<>(list);//注意!!!
                getchildMenu(list1, menu, vineTree1);
            }
        }
    }

现在看来,只能是以前对于这块的理解还不透彻。每一次迭代里的list都应是一个新的list,对于一个list的深层次迭代,对象会丢失,其修改次数不在本次迭代的控制范围之内,所以会报错!!如果没有注意那行,就会报错上述错误!


上一篇下一篇

猜你喜欢

热点阅读