Collections.synchronizedList()源码理解

回顾集合相关知识的时候发现,list集合想要保证线程安全除了使用

vector和Class CopyOnWriteArrayList<E>之外还可以通过Collections.synchronizedList()

获取一个线程安全的集合,就看看他具体是如何实现的

 public static <T> List<T> synchronizedList(List<T> list) {
        return (list instanceof RandomAccess ?
                new SynchronizedRandomAccessList<>(list) :
                new SynchronizedList<>(list));
    }

首先是判断一下是否实现了RandomAccess,这个接口是支持随机访问的,这里可以简单的理解为传入ArrayList和LinkedList(链表结构不支持随机访问)

这里返回了两个集合

SynchronizedRandomAccessList
SynchronizedList
 SynchronizedRandomAccessList(List<E> list) {
            super(list); //这里指向父级
        }

//点进去

 SynchronizedList(List<E> list) {
            super(list); //又指向父级
            this.list = list;
        }

//点进去

        final Collection<E> c;  // Backing Collection
        final Object mutex;    

 SynchronizedCollection(Collection<E> c) {
            this.c = Objects.requireNonNull(c);
            mutex = this;  //这里就是传传进来的集合作为锁对象
        }

super( )的用法
        super( ) : super( )其实就相当于一个指向基类的指针,(Java中没有指针,但是可以这样理解)。至于用法有一下三种形式:

       1. super.XXX( 这里的XXX指的是父类的成员变量名即父类的属性,或者对象名)

       2. super.XXX( ) ( 这里的XXX是父类中的其中一个方法名)

       3. super( ) ( 这种形式指的是:调用父类没有参数的构造方法(也叫构造函数)注意: 这里super( ) 只能放在子类的构造方法里面,并且只能放在构造方法的首句)

       4. super( x,y,z...) (此形式指:调用父类有参数的构造方法,也必须放在子类的构造方法(成员方法不可以)里面,并且只能放在构造方法的首句。其中x,y,z是指的与父类此有参构造方法中参数数据类型相对应的子类中的参数)

到这里是把我们传入的集合作为了锁,接着看他的添加方法

  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);}
        }

可以看出他的方法,都使用synchronized关键字,这里他与Vector的区别就在这synchronized的位置不同,也就是锁粒度不同,如下图

    /**
    *
    * Vector的add方法
    *
    */


  public synchronized E set(int index, E element) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

 
    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

相对的这种方式获取的线程安全的集合比Vector效率会略高

其本质原理还是通过synchronized来保证的线程安全

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值