java5同步集合類的應用

1、概述

    一、傳統集合類在併發訪問時的問題說明java

    二、傳統方式下用Collections工具類提供的synchronizedCollection方法來得到同步集合,分析該方法的實現源碼。安全

    三、傳統方式下的Collection在迭代集合時,不容許對集合進行修改。併發

  > 根據AbstractList的checkForComodification方法的源碼,分析產生ConcurrentModificationException異常的緣由。app

    四、Java5中提供了以下一些同步集合類ide

        經過看java.util.concurrent包下的介紹能夠知道有哪些併發集合工具

        > ConcurrentHashMap ui

        > CopyOnWriteArrayList this

        > CopyOnWriteArraySetspa

2、代碼描述

    一、User.java

package com.lh.threadtest.t14;

/***
 * 
* @ClassName: User 
* @Description: TODO
* @author Liu
* @date 2018年1月18日 下午8:43:50 
*
 */
public class User implements Cloneable {
	private String name;
	private int age;

	public User(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (!(obj instanceof User)) {
			return false;
		}
		User user = (User) obj;
		// if(this.name==user.name && this.age==user.age)
		if (this.name.equals(user.name) && this.age == user.age) {
			return true;
		} else {
			return false;
		}
	}

	public int hashCode() {
		return name.hashCode() + age;
	}

	public String toString() {
		return "{name:'" + name + "',age:" + age + "}";
	}

	public Object clone() {
		Object object = null;
		try {
			object = super.clone();
		} catch (CloneNotSupportedException e) {
		}
		return object;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}
}

    二、CollectionTest.java

package com.lh.threadtest.t14;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;


/***
 * 
* @ClassName: CollectionTest
* @Description: TODO
* @author Liu
* @date 2018年1月18日 下午8:44:27 
*
 */
public class CollectionTest {
	public static void main(String[] args) {
		Collections.synchronizedCollection(null);
		
//		Collection users = new ArrayList();
		Collection users = new CopyOnWriteArrayList();
		users.add(new User("張三", 28));
		users.add(new User("李四", 25));
		users.add(new User("王五", 31));
		Iterator itrUsers = users.iterator();
		while (itrUsers.hasNext()) {
			User user = (User) itrUsers.next();
			if ("張三".equals(user.getName())) {
				users.remove(user);
				// itrUsers.remove();
			} else {
				System.out.println(user);
			}
		}
	}
}

    三、Collections.synchronizedMap(Map<Object  obj, Object obj> map)源碼

private static class SynchronizedMap<K,V>
        implements Map<K,V>, Serializable {
        private static final long serialVersionUID = 1978198479659022715L;

        private final Map<K,V> m;     // Backing Map
        final Object      mutex;        // Object on which to synchronize

        SynchronizedMap(Map<K,V> m) {
            this.m = Objects.requireNonNull(m);
            mutex = this;
        }

        SynchronizedMap(Map<K,V> m, Object mutex) {
            this.m = m;
            this.mutex = mutex;
        }

        public int size() {
            synchronized (mutex) {return m.size();}
        }
        public boolean isEmpty() {
            synchronized (mutex) {return m.isEmpty();}
        }
        public boolean containsKey(Object key) {
            synchronized (mutex) {return m.containsKey(key);}
        }
        public boolean containsValue(Object value) {
            synchronized (mutex) {return m.containsValue(value);}
        }
        public V get(Object key) {
            synchronized (mutex) {return m.get(key);}
        }

        public V put(K key, V value) {
            synchronized (mutex) {return m.put(key, value);}
        }
        public V remove(Object key) {
            synchronized (mutex) {return m.remove(key);}
        }
        public void putAll(Map<? extends K, ? extends V> map) {
            synchronized (mutex) {m.putAll(map);}
        }
        public void clear() {
            synchronized (mutex) {m.clear();}
        }

        private transient Set<K> keySet;
        private transient Set<Map.Entry<K,V>> entrySet;
        private transient Collection<V> values;

        public Set<K> keySet() {
            synchronized (mutex) {
                if (keySet==null)
                    keySet = new SynchronizedSet<>(m.keySet(), mutex);
                return keySet;
            }
        }

        public Set<Map.Entry<K,V>> entrySet() {
            synchronized (mutex) {
                if (entrySet==null)
                    entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
                return entrySet;
            }
        }

        public Collection<V> values() {
            synchronized (mutex) {
                if (values==null)
                    values = new SynchronizedCollection<>(m.values(), mutex);
                return values;
            }
        }

        public boolean equals(Object o) {
            if (this == o)
                return true;
            synchronized (mutex) {return m.equals(o);}
        }
        public int hashCode() {
            synchronized (mutex) {return m.hashCode();}
        }
        public String toString() {
            synchronized (mutex) {return m.toString();}
        }

        // Override default methods in Map
        @Override
        public V getOrDefault(Object k, V defaultValue) {
            synchronized (mutex) {return m.getOrDefault(k, defaultValue);}
        }
        @Override
        public void forEach(BiConsumer<? super K, ? super V> action) {
            synchronized (mutex) {m.forEach(action);}
        }
        @Override
        public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
            synchronized (mutex) {m.replaceAll(function);}
        }
        @Override
        public V putIfAbsent(K key, V value) {
            synchronized (mutex) {return m.putIfAbsent(key, value);}
        }
        @Override
        public boolean remove(Object key, Object value) {
            synchronized (mutex) {return m.remove(key, value);}
        }
        @Override
        public boolean replace(K key, V oldValue, V newValue) {
            synchronized (mutex) {return m.replace(key, oldValue, newValue);}
        }
        @Override
        public V replace(K key, V value) {
            synchronized (mutex) {return m.replace(key, value);}
        }
        @Override
        public V computeIfAbsent(K key,
                Function<? super K, ? extends V> mappingFunction) {
            synchronized (mutex) {return m.computeIfAbsent(key, mappingFunction);}
        }
        @Override
        public V computeIfPresent(K key,
                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            synchronized (mutex) {return m.computeIfPresent(key, remappingFunction);}
        }
        @Override
        public V compute(K key,
                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            synchronized (mutex) {return m.compute(key, remappingFunction);}
        }
        @Override
        public V merge(K key, V value,
                BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
            synchronized (mutex) {return m.merge(key, value, remappingFunction);}
        }

        private void writeObject(ObjectOutputStream s) throws IOException {
            synchronized (mutex) {s.defaultWriteObject();}
        }
    }

3、關鍵點

    一、傳統的ArrayList/ArraySet/HashMap集合類線程不安全的緣由?線程

    二、ConcurrentModificationException異常發生的緣由?

相關文章
相關標籤/搜索