zoukankan      html  css  js  c++  java
  • Collections.synchronizedList使用

    1.SynchronizedList类具体代码:

      static class SynchronizedList<E>
            extends SynchronizedCollection<E>
            implements List<E> {
            private static final long serialVersionUID = -7754090372962971524L;
    
            final List<E> list;
    
            SynchronizedList(List<E> list) {
                super(list);
                this.list = list;
            }
            SynchronizedList(List<E> list, Object mutex) {
                super(list, mutex);
                this.list = list;
            }
    
            public boolean equals(Object o) {
                if (this == o)
                    return true;
                synchronized (mutex) {return list.equals(o);}
            }
            public int hashCode() {
                synchronized (mutex) {return list.hashCode();}
            }
    
            public E get(int index) {
                synchronized (mutex) {return list.get(index);}
            }
            public E set(int index, E element) {
                synchronized (mutex) {return list.set(index, element);}
            }
            public void add(int index, E element) {
                synchronized (mutex) {list.add(index, element);}
            }
            public E remove(int index) {
                synchronized (mutex) {return list.remove(index);}
            }
    
            public int indexOf(Object o) {
                synchronized (mutex) {return list.indexOf(o);}
            }
            public int lastIndexOf(Object o) {
                synchronized (mutex) {return list.lastIndexOf(o);}
            }
    
            public boolean addAll(int index, Collection<? extends E> c) {
                synchronized (mutex) {return list.addAll(index, c);}
            }
    
            public ListIterator<E> listIterator() {
                return list.listIterator(); // Must be manually synched by user
            }
    
            public ListIterator<E> listIterator(int index) {
                return list.listIterator(index); // Must be manually synched by user
            }
    
            public List<E> subList(int fromIndex, int toIndex) {
                synchronized (mutex) {
                    return new SynchronizedList<>(list.subList(fromIndex, toIndex),
                                                mutex);
                }
            }
    
            @Override
            public void replaceAll(UnaryOperator<E> operator) {
                synchronized (mutex) {list.replaceAll(operator);}
            }
            @Override
            public void sort(Comparator<? super E> c) {
                synchronized (mutex) {list.sort(c);}
            }
    
            private Object readResolve() {
                return (list instanceof RandomAccess
                        ? new SynchronizedRandomAccessList<>(list)
                        : this);
            }
        }
    

    1.使用方式

    官方文档就是下面的使用方式

    List list = Collections.synchronizedList(new ArrayList());
          ...
      synchronized (list) {
          Iterator i = list.iterator(); // Must be in synchronized block
          while (i.hasNext())
              foo(i.next());
      }
    

    既然封装类内部已经加了对象锁,为什么外部还要加一层对象锁?

    看源码可知,Collections.synchronizedList中很多方法,比如equals,hasCode,get,set,add,remove,indexOf,lastIndexOf......

    都添加了锁,但是List中

    Iterator<E> iterator();
    

    这个方法没有加锁,不是线程安全的,所以如果要遍历,还是必须要在外面加一层锁。

    使用Iterator迭代器的话,似乎也没必要用Collections.synchronizedList的方法来包装了——反正都是必须要使用Synchronized代码块包起来的。

    所以总的来说,Collections.synchronizedList这种做法,适合不需要使用Iterator、对性能要求也不高的情况。

    2.SynchronizedList和Vector最主要的区别:

    1. Vector扩容为原来的2倍长度,ArrayList扩容为原来1.5倍
    2. SynchronizedList有很好的扩展和兼容功能。他可以将所有的List的子类转成线程安全的类。
    3. 使用SynchronizedList的时候,进行遍历时要手动进行同步处理 。
    4. SynchronizedList可以指定锁定的对象。

    3.for的注意点与

    for (int i = 0; i < list.size(); i++) {
        System.out.print(list.get(i) + ",");
    }
    
    Iterator iterator = list.iterator();
    while (iterator.hasNext()) {
        System.out.print(iterator.next() + ",");
    }
    
    for (Integer i : list) {
        System.out.print(i + ",");
    }
    

    第一种是普通的for循环遍历、第二种是使用迭代器进行遍历,第三种我们一般称之为增强for循环(for each)

    可以看到,第三种形式是JAVA提供的语法糖,这里我们剖洗一下,这种增强for循环底层是如何实现的。

       for (Integer i : list) {
           System.out.println(i);
       }
    

    反编译后:

        Integer i;
        for(Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(i)){
            i = (Integer)iterator.next();        
        }
    

    如果在Vector,Collections.synchronizedList使用增强for循环,就必须在外面单独加锁,因为它不是单单一个操作,不是原子性的,如果在遍历的过程中,进行add,remove操作,就会抛出异常。

    参考:

    通过Collections.synchronizedList获取安全的list后,为何还要用synchronized修饰?

    SynchronizedList和Vector的区别

    【集合类型的并发】Collections.synchronizedList

    ArrayList、Vector和Collections.synchronizedList()

    Java中的增强for循环(for each)的实现原理与坑

  • 相关阅读:
    bzoj 4012: [HNOI2015]开店
    POJ 1054 The Troublesome Frog
    POJ 3171 Cleaning Shifts
    POJ 3411 Paid Roads
    POJ 3045 Cow Acrobats
    POJ 1742 Coins
    POJ 3181 Dollar Dayz
    POJ 3040 Allowance
    POJ 3666 Making the Grade
    洛谷 P3657 [USACO17FEB]Why Did the Cow Cross the Road II P
  • 原文地址:https://www.cnblogs.com/hongdada/p/10931891.html
Copyright © 2011-2022 走看看