同時プログラミングトラップシリーズ(一)同期不完全


同期ブロックはすべてのシーンに上書きされていません.
 
import java.util.HashMap;
import java.util.Map;

public class CacheManage {
	private Map<String, String> cache = new HashMap<String, String>();

	public static int THREADS_COUNT = 2;

	public void fresh() {
		synchronized (cache) {
			cache.clear();
		}
	}

	public void put(String key, String value) {
		synchronized (cache) {
			cache.put(key, value);
			System.out.println(Thread.currentThread().getName()
					+ "  cache.put--------" + value);
		}
	}

	public String get(String key) {
		System.out.println(Thread.currentThread().getName()
				+ "  cache.get-----" + cache.get(key));
		return cache.get(key);
	}

	public static void main(String[] args) {
		final CacheManage cacheManage = new CacheManage();
		Thread[] threads = new Thread[THREADS_COUNT];
		for (int i = 0; i < THREADS_COUNT; i++) {
			threads[i] = new Thread(new Runnable() {
				public void run() {
					for (int i = 0; i < 10; i++) {
						cacheManage.put("a", i + 1 + "");
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						cacheManage.get("a");
					}
				}
			});
			threads[i].start();
		}
	}
}

上のキャッシュ管理クラスは、2つのスレッドを起動してアクセスし、各スレッドが行うことは同じで、put後get、印刷の結果は:
 
Thread-0  cache.put--------1
Thread-1  cache.put--------1
Thread-0  cache.get-----1
Thread-0  cache.put--------2
Thread-1  cache.get-----1
...
解析:Thread 0は、データを書き込み(キャッシュを2に変更)すると同時に、thread 1がデータを取り出し、thread 1が古いキャッシュを読み出します.
まとめ:読み書きができない読み書きができない同時読み書きができない