Collections.synchronizedList 工厂方法

来源:互联网 发布:js改变button标签文字 编辑:程序博客网 时间:2024/05/22 00:32
 Collections.synchronizedList 工厂方法

通常的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( ' ');
        }
    }

0 0