并发编程陷阱系列 (一)同步不完全
程序员文章站
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读取了旧的缓存。
总结:读时不能写 写时不能读 可以并发读 不能并发写
上一篇: 正确书写单例模式
下一篇: JAVA基础 之 ResultSet
推荐阅读
-
并发编程(一)------同步类容器
-
Java并发编程系列一:Future和CompletableFuture解析与使用
-
Python并发编程系列之常用概念剖析:并行 串行 并发 同步 异步 阻塞 非阻塞 进程 线程 协程...
-
Java并发编程系列一:Future和CompletableFuture解析与使用
-
并发编程(一)------同步类容器
-
并发编程陷阱系列(五)double check
-
并发编程陷阱系列(八)不要吞食CountDownLatch的线程异常
-
并发编程陷阱系列(六)高并发环境下使用性能较低的Map
-
并发编程陷阱系列(四)volatile与变量脏读
-
并发编程陷阱系列(三)使用Thread.interrupt()中断线程