打小就馋 2021-07-07 23:25 采纳率: 0%
浏览 31

麻烦分析一下原因,下面贴了代码,具体操作和结果在注释中做了介绍。

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        int threadCount = 10;
        int cap = 1000 * threadCount;
        Map<String, Integer> unsafeMap = new HashMap<>(cap);
        Map<String, Integer> safeMap = new Hashtable<>(cap);


        for (int i = 0; i < threadCount; i++) {
            /*
            safeMap早于unsafeMap启动结果:
                safeMap = 10000
                unsafeMap = 小于10000

            unsafeMap早于safeMap启动结果:
                safeMap = 9500
                unsafeMap = 小于10000
             */
            new Runner(unsafeMap).start();
            new Runner(safeMap).start();
        }

        while(Thread.activeCount() > 2){
            Thread.yield();
        }

        System.out.println("safeMap = " + safeMap.size());
        System.out.println("unsafeMap = " + unsafeMap.size());
    }
}

class Runner extends Thread {
    Map map;

    Runner(Map map) {
        this.map = map;
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            map.put(this.getName() + i, i);
        }
    }
}

请问,Hashtable后启动线程时,上限稳定在9500是什么原因导致的,感谢各位大佬~

补充:我试了线程数,threadCount的个位是1-5时没有问题(比如1,12,23等等),个位6-0(比如7,16,29等等),每增加1条,总数就少100,所以10条线程9500,期待大佬贴源码解惑,感激不尽~

  • 写回答

1条回答 默认 最新

  • 关注

    恭喜您!发现了新大陆,这就是传说中的线程不安全并发导致的库存超卖问题;
    原理:
    两个线程同时运行到map.put(key,value),第一个线程获取到了下一个保存点,第二个线程也获取到了下一个保存点,第一个线程用下一个保存点存了key-value,第二个线程也用下一个保存点存了key-value,结果下一个保存点就职存了第二个线程的key-value,所以就少了一个,以此类推,就会出现好几个,线程越多,少的越多

    评论

报告相同问题?

悬赏问题

  • ¥15 这个如何解决详细步骤
  • ¥15 在微信h5支付申请中,别人给钱就能用我的软件,这个的所属行业是啥?
  • ¥30 靶向捕获探针设计软件包
  • ¥15 react-diff-viewer组件,如何解决数据量过大卡顿问题
  • ¥20 遥感植被物候指数空间分布图制作
  • ¥15 安装了xlrd库但是import不了…
  • ¥20 Github上传代码没有contribution和activity记录
  • ¥20 SNETCracker
  • ¥15 数学建模大赛交通流量控制
  • ¥15 为什么我安装了open3d但是在调用的时候没有报错但是什么都没有发生呢