同步类容器:如古老的Vector、Hashtable,这类容器的同步功能其实都是有JDK的Conllections.synchronized...等工厂方法去创建实现的。其实底层的机制无非就是使用传统的synchronized关键字对每个公用的方法都进行同步,是的每次只能有一个线程访问容器的状态,这很明显不能满足我们今天互联网时代的并发要求,在保证线程安全的时候,也必须要有足够的性能;
下面的代码会出现:ConcurrentModificantionException
package com.taikang.demo01;
import java.util.Iterator;
import java.util.Vector;
public class Tickets {
public static void main(String[] args) {
final Vector<String> tickets = new Vector<>();
for (int i = 0; i < 100; i++) {
tickets.add("彦彦" + i);
}
for (Iterator iterator = tickets.iterator(); iterator.hasNext();) {
String string = (String)iterator.next();
tickets.remove(20);
}
}
}
如果在单线程实现安全的话,我们可以通过一个公共类的方法:
List<String> list = Collections.synchronizedList(new LinkedList<String>());
Map<String, String> map = Collections.synchronizedMap(new HashMap<String,String>());
通过这样情况,就得到了一个安全的容器;
下面,我们来看看Collections.synchronizedList(new LinkedList<String>());源码:
/**
* Returns a synchronized (同步)(thread-safe) list backed by the specified(指定)
返回由指定列表支持的同步(线程安全)list。
* list. In order to guarantee(保证) serial access(串行访问或者连续的访问), it is critical(危险) that
* <strong>all</strong> access to the backing list is accomplished(完成的)
* through the returned list.<p>
*
* It is imperative that the user manually synchronize on the returned
* list when iterating over it:
在迭代时,用户必须在返回的列表上手动同步:
*
* List list = Collections.synchronizedList(new ArrayList());
* ...
* synchronized (list) {
* Iterator i = list.iterator(); // Must be in synchronized block
* while (i.hasNext())
* foo(i.next());
* }
* </pre>
* Failure to follow this advice may result in non-deterministic behavior.
*
* <p>The returned list will be serializable if the specified list is
* serializable.
*
* @param list the list to be "wrapped" in a synchronized list.
* @return a synchronized view of the specified list.
*/
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list) :
new SynchronizedList<>(list));
}
static <T> List<T> synchronizedList(List<T> list, Object mutex) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list, mutex) :
new SynchronizedList<>(list, mutex));
}