ConcurrentHashMap只能保证单个操作的原子性,你先get再put,整个操作不是原子性操作,因此是会出现覆盖的问题的。用java.util.concurrent.ConcurrentHashMap#replace(K, V, V)方法的话需要加上失败重试,不然在并发的情况下基本是会出现一个线程无法完成替换的情况的。
这个需求使用java.util.concurrent.ConcurrentHashMap#computeIfPresent方法实现起来会方便一点。
jdk7可能没有这个方法,需要jdk8或以上版本
public static void main(String[] args) throws InterruptedException {
final ConcurrentHashMap map = new ConcurrentHashMap<>();
map.put(3, "null, null");
ExecutorService executorService = Executors.newFixedThreadPool(2);
//模拟并发
CountDownLatch latch = new CountDownLatch(1);
Runnable replace = () -> {
try {
//模拟准备时间
Thread.sleep(ThreadLocalRandom.current().nextLong(3000));
//等待
System.out.println(String.format("线程%s就绪@%d", Thread.currentThread().getId(), System.currentTimeMilli