欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

并发编程陷阱系列 (一)同步不完全

程序员文章站 2022-03-02 08:48:59
...

同步块未覆盖到所有场景。

 

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

...

分析:Thread0在写数据(将缓存修改成2)的同时,thread1将数据取出来了,thread1读取了旧的缓存。

总结:读时不能写 写时不能读  可以并发读  不能并发写