Collections Collections.synchronizedCollection 集合的同步控制

来源:互联网 发布:网络播放量多少 编辑:程序博客网 时间:2024/06/06 00:14

Collections Collections.synchronizedCollection 集合的同步控制

Collections类中提供了多个synchronizedXxx方法:
该方法返回指定集合对象对应的同步对象,解决多线程并发访问集合时线程的安全问题

最常用的集合类有List、Set、Map等,而集合框架中经常使用的三个实现类: HashSet、ArrayList、HashMap都是线程不安全的,Collections提供了多个静态方法用于创建同步集合:

Collection c = Collections.synchronizedCollection(new ArrayList());List list = Collections.synchronizedList(new ArrayList());Set set = Collections.synchronizedSet(new HashSet());Map map = Collections.synchronizedMap(new HashMap());static class SynchronizedCollection<E> implements Collection<E>, Serializable {      // use serialVersionUID from JDK 1.2.2 for interoperability      private static final long serialVersionUID = 3053995032091335093L;      final Collection<E> c;  // Backing Collection      final Object mutex;     // Object on which to synchronize      SynchronizedCollection(Collection<E> c) {          if (c==null)  throw new NullPointerException();          this.c = c;          mutex = this;      }      SynchronizedCollection(Collection<E> c, Object mutex) {          this.c = c;          this.mutex = mutex;      }      ...}  

java.util.Collections.synchronizedCollection()方法的声明。
public static Collection synchronizedCollection(Collection c)
功能:方法用于获得同步的(线程安全的)集合的指定集合的支持
参数c: 在同步集合的被“包装”的集合
返回值
在方法调用返回指定集合的同步视图。

static class SynchronizedRandomAccessList<E> extends SynchronizedList<E>  implements RandomAccess {      static final long serialVersionUID = 1530674583602358482L;     SynchronizedRandomAccessList(List<E> list) {          super(list);      }      SynchronizedRandomAccessList(List<E> list, Object mutex) {          super(list, mutex);      }      public List<E> subList(int fromIndex, int toIndex) {          synchronized(mutex) {              return new SynchronizedRandomAccessList<E>(list.subList(fromIndex, toIndex), mutex);          }      }      private Object writeReplace() {          return new SynchronizedList<E>(list);      }  }  

java.util.Collections.synchronizedList()方法的声明:

public static <T> List<T> synchronizedList(List<T> list) {  return (list instanceof RandomAccess ?                 new SynchronizedRandomAccessList<T>(list) :                 new SynchronizedList<T>(list));//根据不同的list类型最终实现不同的包装类。  } 

功能:
返回列表的同步(线程安全的)列表,对线程安全的List对象,当线程访问时,需获取到该对象的锁才能进行(而不管它是否处于synchronized 同步块中)。
参数list:
需转换成线程安全的列表
当有一个线程获取到该对象的锁后,那么其他线程无论是否使用syn同步块,在调用add,remove等方法时,都会等待获取锁的线程执行完毕后才执行

SynchronizedList对部分操作加上了synchronized关键字以保证线程安全。但其iterator()操作还不是线程安全的(SynchronizedList适合不需要使用Iterator的多线程使用环境)。部分SynchronizedList的代码如下:

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 ListIterator<E> listIterator() {      return list.listIterator(); // Must be manually synched by user,否则仍然可能抛出ConcurrentModificationException  }  public ListIterator<E> listIterator(int index) {      return list.listIterator(index); // Must be manually synched by user,否则仍然可能抛出ConcurrentModificationException}

//SynchronizedMap类是定义在Collections中的一个静态内部类。它实现了Map接口,并对其中的每一个方法实现,通过synchronized 关键字进行了同步控制

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {      return new SynchronizedMap<K,V>(m);  } 

mutex就是当前的SynchronizedCollection对象,而SynchronizedRandomAccessList继承自SynchronizedList,SynchronizedList又继承自SynchronizedCollection,所以SynchronizedRandomAccessList中的mutex也就是SynchronizedRandomAccessList的this对象

1、Collections.synchronizedCollection()// create vector object Vector<String> vector = new Vector<String>();vector.add("1");// create a synchronized viewCollection<String> c = Collections.synchronizedCollection(vector); System.out.println("Synchronized view is :"+c);

2、Collections.synchronizedList()
List list = Collections.synchronizedList(new ArrayList()); //ArrayList是非线性安全,此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的

synchronized (list) {    Iterator i = list.iterator(); // Must be in synchronized block    while (i.hasNext())          System.out.println("list: "+i.next());} 

// create List object
List list = new ArrayList(); //在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException

list.add("1"); // add first item// create a synchronized listList<String> synlist = Collections.synchronizedList(list); //synlist就是线程安全的List<String> 对象new Thread(){      public void run() {          synchronized (synlist) {              try {                  Thread.sleep(100);              }             catch (InterruptedException e) {              };              synlist.add("2");              System.out.println("Operation1 synlist: "+synlist.size() + ", synlist item2: "+synlist.get(2));          }      };  }.start();   new Thread(){      public void run() {          synlist.add("3");          System.out.println("Operation2 synlist: "+synlist.size()+", synlist item2: "+synlist.get(2));      };  }.start(); 

3、Collections.synchronizedMap()

Map<String,String> map = Collections.synchronizedMap(new TreeMap<String,String>());map.put("key1","value1");map.put("key2","value2");Set<Entry<String,String>> entries = map.entrySet();Iterator<Entry<String,String>> iter = entries.iterator();synchronized (map) {    while(iter.hasNext()){        System.out.println(iter.next());         //迭代元素时可能会抛出ConcurrentModificationException异常,所以可加上同步机制synchronized        map.remove("key2");      }}
阅读全文
0 0
原创粉丝点击