通常的Map,Set,List实现都不是线程安全的,通过这些工厂方法可以得到相应的同步容器,相当于增强了访问控制,把一个链表对象传递过来后,我们都通过返回的这个链表对象来进行各种操作(都是同步方法),而不再操纵底层的那个链表。此外,在Vector和同步封装器类中是用内置锁来来支持客户端加锁,所以我们可以进行扩展。
在对对链表迭代的过程中也要注意加锁,否则在迭代的过程中,如果其他某个线程改变了容器的属性,next,hasNext方法就会抛出ConcurrentModificationException
异常(而诸如ConcurrentHashMap的并发容器不需要迭代过程加锁)。更重要的是,要防止隐藏迭代,如果对某个容器调用toString方法的时候。下面是对应的代码。
1.迭代的时候要同步。
List<Integer> safeList = Collections. synchronizedList( new ArrayList<Integer>());
synchronized (safeList)
{
Iterator<Integer> i = safeList.iterator(); // Must be in synchronized block
while (i.hasNext())
System. out.println(i.next());
}
2.隐藏迭代器。
public class HiddenIterator
{
private final Set<Integer> set = new HashSet<Integer>();
public synchronized void add(Integer
i) {
set.add(i);
}
public synchronized void remove(Integer
i) {
set.remove(i);
}
public void addTenThings()
{
Random r = new Random();
for ( int i
= 0; i < 10; i++)
add(r.nextInt());
System. out.println( "DEBUG:
added ten elements to " + set); //这里
}
}
2.容器中toString方法的实现。
public String toString() {
Iterator<E> it = iterator();
if (!
it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append( ‘[‘);
for (;;)
{
E e = it.next();
sb.append(e == this ? "(this
Collection)" : e);
if (!
it.hasNext())
return sb.append( ‘]‘).toString();
sb.append( ‘,‘).append( ‘
‘);
}
}