谁帮忙看看这段 Java 并发代码 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
twogoods
V2EX    Java

谁帮忙看看这段 Java 并发代码

  •  
  •   twogoods 2017-04-22 14:35:34 +08:00 2950 次点击
    这是一个创建于 3170 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我开了 100 个线程用同一个 id 分别去请求这两个方法,把这 100 次方法执行时间的平均值取出来,并且相同的方法重复做了三次得到结果: a: 24907.9ms, b: 24831.1ms ,看结果方法 b 好一点,但这个差距是不是很小啊?

    @Controller @RequestMapping("/bench/") public class BenchController { private static Object[] lockObj; rivate static AtomicReference<Integer>[] locks; static { lockObj = new Object[100]; for (int i = 0; i < lockObj.length; i++) { lockObj[i] = new Object(); } locks = new AtomicReference[100]; for (int i = 0; i < locks.length; i++) { locks[i] = new AtomicReference<Integer>(null); } } @RequestMapping("a") @ResponseBody public long a(int id) throws Exception { long start = System.currentTimeMillis(); int index = id % 100; synchronized (lockObj[index]) { Thread.sleep(500); } long result=System.currentTimeMillis() - start; System.out.println(result); return result; } @RequestMapping("b") @ResponseBody public long b(int id) throws Exception { long start = System.currentTimeMillis(); int index = id % 100; while (!locks[index].compareAndSet(null, id)) { } Thread.sleep(500); locks[index].compareAndSet(id, null); long result=System.currentTimeMillis() - start; System.out.println(result); return result; } } 
    6 条回复    2017-04-22 17:02:52 +08:00
    sorra
        1
    sorra  
       2017-04-22 14:44:43 +08:00
    sleep 是有误差的,你的测试可能是无效的。可以在方法内循环大量次数来测试,也许能有效果
    sagaxu
        2
    sagaxu  
       2017-04-22 14:59:09 +08:00
    sleep 一下要 500ms , lock 一下是不到 1ms 的, sleep 本身的误差已经远大于 lock 的开销。结论,这测试就是胡乱测的。 JVM 的 jit 预热,这里更加看不到了。
    twogoods
        3
    twogoods  
    OP
       2017-04-22 15:21:40 +08:00 via Android
    @sagaxu 确实是自己瞎搞的,就是想看看有锁与无锁的差别有多大,求指导
    Ouyangan
        4
    Ouyangan  
       2017-04-22 15:22:57 +08:00
    二楼的说法靠谱
    记得 JDK1.6 的 JIT C2 策略阈值是 10000 , 楼主可以先在静态代码块中先跑个 10000 次 ,触发 JIT 后再做比较 .

    推荐补补 JVM 类执行机制的知识
    hyperdak
        5
    hyperdak  
       2017-04-22 15:31:45 +08:00   3
    micro benchmark 会被 gc 、 jit 、不正确的代码影响,你得到结果本身就是错的。

    正确的 java benchmark 要用 JMH 这种套件来做,它包含了预热和防止代码被 DCE 。在正确使用 JMH 的时候,你就可以得到一个正确的 benchmark 结果了
    0915240
        6
    0915240  
       2017-04-22 17:02:52 +08:00
    既然是要获取基准测试并且感知到小差距,建议换到用 jmh 试试看。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2706 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 14:14 PVG 22:14 LAX 06:14 JFK 09:14
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86