线程安全的集合中的Collections中的工具方法(获得线程安全集合)和CopyOnWtiteArrayList

Collections中的工具方法

public  static  <T>  Collection<T>  synchronizedCollection(Collection<T>  c)(获得一个Collection安全集合)

public static <T> List<T> synchronizedList(List<T> list)(获得一个List安全集合

public static <T> Set<T> synchronizedSet(Set<T> s)(获得一个Set安全集合)

public static <K , V> Map<K , V> synchronizedMap(Map<K , V> m)(获得一个Map安全集合)

public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)

public static <K, V> SortedMap<K, V> synchronizedSortedMap(SortedMap<K, V> m)

JDK1.2提供,接口统一、维护性高,但性能没有提升,均以synchronized实现

用public static <T> List<T> synchronizedList(List<T> list)举例:

创建方式
List<String> li = new ArrayList<String>();
List<String> list = Collections.synchronizedList(li);

返回一个新的List类型的集合对象
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list) :
new SynchronizedList<>(list));
}

子类构造方法
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}

父类构造方法
SynchronizedCollection(Collection<E> c) {

this.c = Objects.requireNonNull(c);//非空判断
mutex = this;
}
final Object mutex
final Collection<E> c

 

Final Object mutex作为同步代码块的对象,进行加锁,保证线程安全
public boolean add(E e) {
synchronized (mutex) {return c.add(e);}
}

 

 

 

CopyOnWtiteArrayList

线程安全的ArrayList,加强版读写分离

写有锁,读无锁,读写之间不阻塞,优于读写锁

写入时,先copy一个容器副本、在添加新元素,最后替换引用

使用方式与ArrayList无异
List<String> list = new CopyOnWriteArrayList<String>();

写有锁

都将底层数组做了一次复制,写的是新数组,完成赋值后,再将新数组替换掉旧数组!
每调用一次,底层方法扩容一次!

public boolean add(E e) {
final ReentrantLock lock = this.lock;//将原来建好的锁赋值给变量,
lock.lock(); //获取锁                               相当于建了一个新锁 
try {
Object[] elements = getArray();//获得一个数组
int len = elements.length;//数组的长度,初始为0
Object[] newElements = Arrays.copyOf(elements, len + 1);//扩容操作
newElements[len] = e;//将新数组的下标0存入传过来的e
setArray(newElements);//将新创建的数组调用setArray
return true;//成功返回true
} finally {
lock.unlock();//释放锁
}
}

其中用到的方法:
private transient volatile Object[] array;

final Object[] getArray() {
return array;
}
返回一个存好array数组

final void setArray(Object[] a) {
array = a;
}
将传过来的数组存入array

读无锁

读的是写操作完成之前的旧数组!写完之后,才能读到的新数组的新值
public E get(int index) {
return get(getArray(), index);
}

final Object[] getArray() {
return array;
}
返回一个array数组

private E get(Object[] a, int index) {
return (E) a[index];
}
返回一个数组index下标的值

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值