V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
corningsun
V2EX  ›  Java

Java .util.Date.getTime() 两次调用不相等

  •  
  •   corningsun · 2021-03-12 16:39:41 +08:00 · 2559 次点击
    这是一个创建于 1359 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 TestNG 模拟 20 个线程 调用 10000 次,有概率都能重现这个错误

    有老哥研究过么?

    测试用例:

    https://gist.github.com/corningsun/a9a0527edc2f5dc5f3659424d1b8a224

    17 条回复    2021-03-14 11:51:01 +08:00
    tesguest123
        1
    tesguest123  
       2021-03-12 16:57:14 +08:00 via iPhone
    时间不是一直在走嘛……
    dqzcwxb
        2
    dqzcwxb  
       2021-03-12 16:59:58 +08:00
    jwenjian
        3
    jwenjian  
       2021-03-12 17:01:12 +08:00 via iPhone   ❤️ 2
    可能是 JDK 的 bug [doge]
    anonydmer
        4
    anonydmer  
       2021-03-12 17:01:18 +08:00
    不是,他那问题是个典型并发问题。。。
    yazoox
        5
    yazoox  
       2021-03-12 17:01:24 +08:00
    永远都不会相等吧?相等那就是 bug 了......
    The java.util.Date.getTime() method returns how many milliseconds have passed since January 1, 1970, 00:00:00 GMT

    google 了一下:
    https://www.tutorialspoint.com/java/util/date_gettime.htm
    RedBeanIce
        6
    RedBeanIce  
       2021-03-12 17:03:40 +08:00
    可能是 JDK 的 bug [doge]
    anonydmer
        7
    anonydmer  
       2021-03-12 17:04:27 +08:00
    楼上的兄弟们,他那个时间是在每次测试之前重新赋值了的,@BeforeMethod 干的;但是他的测试方法是个多线程运行的,一组线程每个来运行测试前都执行一遍赋值,个个去改那个变量由不做任何同步,并发下能一致才见了鬼了
    jwenjian
        8
    jwenjian  
       2021-03-12 17:09:44 +08:00 via iPhone
    本地打不开 gist 挂了代理才看见,那不是 JDK 的 bug,是楼主自己的 bug
    dreamist
        9
    dreamist  
       2021-03-12 17:13:28 +08:00   ❤️ 1
    典型的线程安全问题,这是因为 setUp() 和 testDateGetTime2 这两个方法的顺序执行不是线程安全的,同时他们之间有共享变量。把 date 和 time 都加上 volatile,同时把 setUp 和 testDateGetTime2 都加上 synchronized 应该就可以了。看起来是因为 testNG 内部没有处理 setUp 方法和测试方法的线程安全问题。
    anonydmer
        10
    anonydmer  
       2021-03-12 17:15:52 +08:00
    怎么能怪 TestNG 呢
    cppgohan
        11
    cppgohan  
       2021-03-12 17:22:52 +08:00
    并行多线程跑用例, setup 初始化的 date 却是全局共享的字段. 给 date 改成 thread local 吧
    shyling
        12
    shyling  
       2021-03-12 17:32:59 +08:00
    建议把 testDateGetTime 删掉
    qwerthhusn
        13
    qwerthhusn  
       2021-03-12 17:53:39 +08:00
    at BeforeMethod 会在每次 at Test 之前执行一次,这样就不线程安全了
    newmlp
        14
    newmlp  
       2021-03-12 18:55:06 +08:00
    恭喜你发现了 jdk 的 bug,屁啊怎么可能,肯定是你的测试代码有问题啊,
    pkookp8
        15
    pkookp8  
       2021-03-12 20:08:36 +08:00
    刚开始学 java
    是不是多线程并发问题?
    before test 初始化了 date 和 time
    date = new Date();
    time = date.getTime();
    单线程的时候 date.getTime()一定等于 time
    多线程进行测试,是不是共用了 date ?导致另一个线程初始化了 date,还没初始化 time,所以 time 和 date.getTime()不相等?
    java 可以打印地址嘛,把 date 和 time 地址打印一下
    corningsun
        16
    corningsun  
    OP
       2021-03-14 08:57:57 +08:00
    @anonydmer
    哈哈哈哈,看来确实是这样的,换成 @BeforeClass 就没问题了,谢谢。


    @pkookp8
    Date date 和 long time 是不同的类型,地址肯定不一样的。
    问题还是共享变量导致的
    pkookp8
        17
    pkookp8  
       2021-03-14 11:51:01 +08:00
    @corningsun 我没表述清楚。
    我想比较不同线程下的 date 地址
    不是说 date 和 time 的地址一样。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2683 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 07:27 · PVG 15:27 · LAX 23:27 · JFK 02:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.