【Java】コレクション ~ マルチスレッド 編~

■ List

 * マルチスレッドに対応するのに適した方法を考える

[1] Collections.synchronizedList()を利用する

List<String> list =  
  Collections.synchronizedList(new ArrayList<String>());  
参考文献
http://www.symmetric.co.jp/blog/archives/29
http://karetta.jp/book-node/java/230442

[2] CopyOnWriteArrayList()を利用する

List<String> list = new CopyOnWriteArrayList<>();

【利点】
  * リストの変更操作で、ConcurrentModificationExceptionをスローしないことを保証
【欠点】
  * 余分にメモリ割当と解放をするため、コストがかかる
参考文献
http://d.hatena.ne.jp/j5ik2o/20090813/1250118023
http://archerblog.blog45.fc2.com/blog-entry-68.html

■ Map

[1] ConcurrentHashMap()を利用する

 * From JDK 1.5
 * !!★注意★!! キーまたは値として null を使用することを許可しない(HashMap とは異なるので注意)
 * アトミック(原子)なputIfAbsent()メソッドを使うと、。

putIfAbsentは以下のコードと等
http://docs.oracle.com/javase/jp/6/api/java/util/concurrent/ConcurrentHashMap.html
http://d.hatena.ne.jp/mokkouyou2001/20081002/1222954543
http://www.syboos.jp/java/doc/ConcurrentHashMap-usage-sample.html

[2] Collections.synchronizedMap()を利用する

 * Iteratorで要素を取り出すときに同期を保証してくれない

 *---
 Map map2 = Collections.synchronizedMap(new HashMap());
 *---
http://kechanzahorumon.hatenadiary.com/entry/2012/10/23/112551
サンプル
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SampleClass {
	private static final int MaxLoopNumber = 100000;
	private static Map<Integer, String> map =
			new ConcurrentHashMap<Integer, String>();
//	private static Map<Integer, String> map =
//			new Hashtable<Integer, String>();
//	private static Map<Integer, String> map =
//			Collections.synchronizedMap(new HashMap<Integer, String>());
	
	private static class SamplePuttingMap extends Thread {
		public void run() {
			for (int i = 0; i < SampleClass.MaxLoopNumber; i++) {
				//map.putIfAbsent(i, "Sample" + i);
				//map.put(i, "Sample" + i);
				synchronized (map) {
					if (map.containsKey(i)) {
						map.remove(i);
					} else {
						map.put(i, "Sample" + i);
					}
				}
				System.out.println("Put [" + i + "] by " + getName());
			}
		}
	}

	public static void main(String[] args) throws InterruptedException {
		long start = System.nanoTime();
		
		SamplePuttingMap t1 = new SamplePuttingMap();
		SamplePuttingMap t2 = new SamplePuttingMap();
		t1.start();
		t2.start();
		t1.join();
		t2.join();
		
		System.out.println(
				"Finish " + ((System.nanoTime() - start) / 1000000) + "[ms]");
	}
}

関連記事

コレクション ~ List 編~

http://blogs.yahoo.co.jp/dk521123/32156111.html

コレクション ~ Map編~

http://blogs.yahoo.co.jp/dk521123/33002154.html

コレクション ~ Set 編~

http://blogs.yahoo.co.jp/dk521123/33006348.html

コレクション ~ Queue 編~

http://blogs.yahoo.co.jp/dk521123/33006366.html

コレクション ~ マルチスレッド 編~

http://blogs.yahoo.co.jp/dk521123/34006868.html