java基础----ArrayList,LinkedList,C

作者: pgydbh | 来源:发表于2018-08-20 16:12 被阅读12次

    总结

    ①ArrayList本质是顺序表,也就是数组
    ②LinkedList本质是链表,双向链表。查找的时候根据大小选择一半遍历。
    ③所以ArrayList的get效率高。
    ④所以LinkedList的put效率高。
    ⑤CopyOnWriteArrayList线程安全。ArrayList与LinkedList线程不安全。
    ⑥CopyOnWriteArrayList在写的时候加锁,保证了写的时候不会copy很多副本。
    引用自:https://www.cnblogs.com/dolphin0520/p/3938914.html

    什么是CopyOnWrite容器
      CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

    线程安全

    ArrayList

    中途报错,线程不安全。

        private static ArrayList<Integer> list = new ArrayList<>();
        private static ExecutorService executorService = Executors.newFixedThreadPool(20);
        public static void main(String[] args){
    
            for (int i = 0; i < 20; i++){
                executorService.execute(new MyRunnable());
            }
            executorService.shutdown();
    
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println(list.size());
        }
    
        private static class MyRunnable implements Runnable{
    
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++){
                    list.add(i);
                }
                System.out.println(list.size());
            }
        }
    }
    
    输出:
    Exception in thread "pool-1-thread-3" java.lang.ArrayIndexOutOfBoundsException: 1950
        at java.util.ArrayList.add(ArrayList.java:463)
        at Main$MyRunnable.run(Main.java:43)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
    

    linkedList

    插入不完全,本来应该有20000个。线程不安全

    public class Main{
        private static List<Integer> list = new LinkedList<>();
        //略
    }
    
    输出:16634
    

    CopyOnWriteArrayList

    线程安全

    public class Main{
        private static List<Integer> list = new CopyOnWriteArrayList<>();
        //略
    }
    
    输出:20000
    

    效率

    public class Main{
        private static ArrayList<Integer> arrayList = new ArrayList<>();
        private static LinkedList<Integer> linkedList = new LinkedList<>();
        public static void main(String[] args){
            //插入
            System.out.println("插入在最后面");
            long s = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++){
                arrayList.add(i);
            }
            System.out.println("10w次插入 arrayList:" + (System.currentTimeMillis() - s) + "ms");
            long s1 = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++){
                linkedList.add(i);
            }
            System.out.println("10w次插入 linkedList:" + (System.currentTimeMillis() - s1) + "ms");
    
            //插入
            System.out.println("插入在最前面");
            long s2 = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++){
                arrayList.add(0, i);
            }
            System.out.println("10w次插入 arrayList:" + (System.currentTimeMillis() - s2) + "ms");
            long s3 = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++){
                linkedList.add(0, i);
            }
            System.out.println("10w次插入 linkedList:" + (System.currentTimeMillis() - s3) + "ms");
    
            //查找
            System.out.println("查找中间");
            long s4 = System.currentTimeMillis();
            for (int i = 0; i < 10000; i++){
                arrayList.get(50000);
            }
            System.out.println("10w次查找 arrayList:" + (System.currentTimeMillis() - s4) + "ms");
            long s5 = System.currentTimeMillis();
            for (int i = 0; i < 10000; i++){
                linkedList.get(99999);
            }
            System.out.println("10w次查找 linkedList:" + (System.currentTimeMillis() - s5) + "ms");
        }
    }
    
    
    输出:
    插入在最后面
    10w次插入 arrayList:5ms
    10w次插入 linkedList:5ms
    插入在最前面
    10w次插入 arrayList:1994ms
    10w次插入 linkedList:5ms
    查找中间
    10w次查找 arrayList:0ms
    10w次查找 linkedList:1428ms
    

    相关文章

      网友评论

        本文标题:java基础----ArrayList,LinkedList,C

        本文链接:https://www.haomeiwen.com/subject/gdjliftx.html