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

老哥们,我老大在循环里写 Thread.sleep,到处都这么写,有问题吗

  •  1
     
  •   Aliberter · 2021-12-01 09:09:24 +08:00 · 8834 次点击
    这是一个创建于 1091 天前的主题,其中的信息可能已经有所发展或是发生改变。

    他为了实现一个定时任务的功能,因为他说 spring 的定时任务不好用,每次跑着跑着就没了,所以想出来这种写个死循环,然后执行一次就休眠一段时间的方法,但是我看 IDE 都会报警告,说禁止在循环里写 Thread.sleep ,我在 stackoverflow 上看了好多解释的帖子,说很浪费资源,发给他看,他之前说这样写不会浪费资源,看了帖子后又说浪费点资源没事,主要是这样实现的定时任务很稳定,求老哥们的意见,这样到底有没有问题?

    yaphets666
        1
    yaphets666  
       2021-12-01 09:12:27 +08:00
    不管有没有问题,听你领导的就行了,他负总责。
    Leonard
        2
    Leonard  
       2021-12-01 09:12:57 +08:00
    不要教老大做事🐶
    chir0n
        3
    chir0n  
       2021-12-01 09:13:12 +08:00   ❤️ 34
    以后性能优化的时候会有用的。
    simonlu9
        4
    simonlu9  
       2021-12-01 09:14:39 +08:00   ❤️ 1
    spring 的定时任务不好用,每次跑着跑着就没了,是因为默认配置的线程池只有一个线程,所以有时候执行不了,自己额外配一下线程池就可以了
    qwerthhusn
        5
    qwerthhusn  
       2021-12-01 09:15:28 +08:00
    主要看 sleep 多久,如果 sleep 1 秒以上。那线程切换占用的一点 CPU 资源都可以忽略不计了
    kop1989
        6
    kop1989  
       2021-12-01 09:16:01 +08:00
    有问题,但是没准更适合你们的场景和成本。
    securityCoding
        7
    securityCoding  
       2021-12-01 09:16:06 +08:00 via Android
    @simonlu9 spring 这个机制的确非常坑
    Aliberter
        8
    Aliberter  
    OP
       2021-12-01 09:18:14 +08:00
    @yaphets666 学会了,老哥职场高人
    Aliberter
        9
    Aliberter  
    OP
       2021-12-01 09:18:24 +08:00
    @Leonard 学到了学到了
    rsyjjsn
        10
    rsyjjsn  
       2021-12-01 09:19:50 +08:00
    小心下次分配给你的任务
    Aliberter
        11
    Aliberter  
    OP
       2021-12-01 09:19:51 +08:00
    @chir0n 哈哈哈,懂了,不过性能现在已经很难看了
    Aliberter
        12
    Aliberter  
    OP
       2021-12-01 09:21:13 +08:00
    @simonlu9 这个我也没具体去排查,定时任务线程池应该是有配,但忘了是在他说问题之前还是之后了,总之后来他就很不愿意用这个了
    Aliberter
        13
    Aliberter  
    OP
       2021-12-01 09:22:20 +08:00
    @qwerthhusn sleep 时间挺长的,但我以为这种写到循环里的话,会持续占据资源不会切换呢
    polobug
        14
    polobug  
       2021-12-01 09:24:22 +08:00
    你能解决岂不是更好= =当然你不能解决的话。。那总得用把
    shenlanAZ
        15
    shenlanAZ  
       2021-12-01 09:24:36 +08:00
    我的前老大还写过 System.gc(); 呢。

    他写的代码让他自己负责,除非要你来全权维护,你可以改成你认为可行的方法。
    Aliberter
        16
    Aliberter  
    OP
       2021-12-01 09:29:06 +08:00
    @polobug 我能解决,我给他提出过 N 多定时任务方案,他看都不看说不能用,就用他写的,属实难顶,所以认了
    sagaxu
        17
    sagaxu  
       2021-12-01 09:32:51 +08:00 via Android   ❤️ 6
    大佬明年一出手,性能提升十倍,对内 PPT 谈 KPI ,对外分享重构案例
    Aliberter
        18
    Aliberter  
    OP
       2021-12-01 09:33:51 +08:00
    @shenlanAZ 我老大是代码可以是他写,但问题一般要追究到我们头上,他不负责,即使我们说之前是你让这么做的,那么他也会说是你当时听错了,然后当即给你提出一种新的方法,让你去改,就是死活不承认自己有错误这种,就因为这种风格底下已经被气的离职了两个了,现在项目也是一团糟,唉
    Aliberter
        19
    Aliberter  
    OP
       2021-12-01 09:35:18 +08:00
    @sagaxu 哈哈哈 精辟
    WytheHuang
        20
    WytheHuang  
       2021-12-01 09:36:19 +08:00
    @Aliberter #18 这还不提桶跑路, 着实不要脸了。
    Aliberter
        21
    Aliberter  
    OP
       2021-12-01 09:38:20 +08:00
    @WytheHuang 我着实想跑了,可是才入职半年,而且也年底了,唉,先忍忍吧,明年来了看情况开溜
    gadfly3173
        22
    gadfly3173  
       2021-12-01 09:39:01 +08:00
    在循环里写 sleep 也不是不能接受的,比如一些循环调用第三方 api 的,为了防止执行过快碰到 api 的 qps 上限,加个 sleep 简单有效
    Spoter
        23
    Spoter  
       2021-12-01 09:39:19 +08:00
    @Aliberter 保留聊天证据
    Aliberter
        24
    Aliberter  
    OP
       2021-12-01 09:39:24 +08:00
    老哥们,点击量高我有点心慌啊,毕竟吐槽老大了,一会我删帖了哈
    Cihua
        25
    Cihua  
       2021-12-01 09:39:48 +08:00
    @Aliberter 18# 针对这种情况我后来遇见问题一律文字沟通,事后甩他脸上,文字发过去如果人过来说,那我就下楼抽根烟等回复
    Aliberter
        26
    Aliberter  
    OP
       2021-12-01 09:40:18 +08:00
    @Spoter 哈哈 都是口头交流 只能录音了下次
    Aliberter
        27
    Aliberter  
    OP
       2021-12-01 09:41:09 +08:00
    @Cihua 学到了,以后多文字沟通,保留证据哈哈
    Aliberter
        28
    Aliberter  
    OP
       2021-12-01 09:41:35 +08:00
    @gadfly3173 ok 明白了 谢谢老哥
    0312birdzhang
        29
    0312birdzhang  
       2021-12-01 09:43:06 +08:00
    @shenlanAZ #15 可以的,有时候 jvm 并不是那么聪明,手动 gc 是有使用场景的。
    dzdh
        30
    dzdh  
       2021-12-01 09:45:08 +08:00
    @Aliberter v2 不准删帖 2333333
    Aliberter
        31
    Aliberter  
    OP
       2021-12-01 09:45:47 +08:00
    @0312birdzhang 说起 gc ,我们现在这个项目,分了 4 个 G 的内存,线程数太多,将近 300 多个,平均每 0.19 秒就要 gc 一次,部署了两天已经 gc 三万多次了,这是不是要炸了啊。。我感觉已经无法直视了,
    Aliberter
        32
    Aliberter  
    OP
       2021-12-01 09:48:35 +08:00
    @dzdh 哈哈哈 忘了 那就这样吧 没事
    tabris17
        33
    tabris17  
       2021-12-01 09:48:49 +08:00
    具体问题具体分析,就一个线程,也不是频繁切换,这么搞完全没问题
    Aliberter
        34
    Aliberter  
    OP
       2021-12-01 09:51:28 +08:00
    @tabris17 ok 明白了 谢谢老哥
    Aliberter
        35
    Aliberter  
    OP
       2021-12-01 09:52:11 +08:00
    老哥们,暂停回复吧,我要搬砖了,谢谢大家哈~
    luozhiyun
        36
    luozhiyun  
       2021-12-01 10:12:11 +08:00
    以我的经验来看,遇到这种事情,最多提醒一次,后面就不要再说了,老大说什么都是对的。你要是觉得在他手上学不到东西,可以跳槽
    JoJoStark
        37
    JoJoStark  
       2021-12-01 10:42:31 +08:00
    @Aliberter 这种甩锅领导太多了,能当领导脸皮都不是一般的厚
    ykk
        38
    ykk  
       2021-12-01 10:46:06 +08:00
    想了下我也在循环里写过 sleep ,为了协调两个进程的时间,不然一个队列灌太快会被冲掉,至今不理解原因
    bxb100
        39
    bxb100  
       2021-12-01 10:48:06 +08:00
    while true + sleep 做定时任务没问题啊
    ligiggy
        40
    ligiggy  
       2021-12-01 11:01:25 +08:00
    非 java ,我的 死循环里面好像都加了 thread.sleep(). 就算在线程里面跑,我也加了
    0xZhangKe
        41
    0xZhangKe  
       2021-12-01 11:09:04 +08:00
    性能问题要有数据对比,你能拿出数据才能证明真的有问题,否则都是空谈。
    xiaoyang7545
        42
    xiaoyang7545  
       2021-12-01 11:20:23 +08:00
    很简单,你能不能有更好的方式来解决现有问题。如果有,就调整一下给他看看是否可以用。如果没有,在那边说这样不行那样不行意义不大。
    ch2
        43
    ch2  
       2021-12-01 11:35:30 +08:00
    又不是不能用.jpg
    liudaolunhuibl
        44
    liudaolunhuibl  
       2021-12-01 11:36:55 +08:00
    sleep 的问题应该是线程状态切换,唤醒和进入休眠都要耗费 CPU 资源的,但是不是太频繁的话理论上还好,虽然算是野路子但是这也是一种解决办法吧,不过更好的是配置 spring 定时任务线程池或者换成其他的框架比如 XxlJob
    easing
        45
    easing  
       2021-12-01 11:42:50 +08:00
    @Aliberter #13 并不是,sleep 会切换出去的(最后走 futex_wait ),如果 sleep 时间挺长,其实没啥问题。而且确实稳定。
    meeop
        46
    meeop  
       2021-12-01 11:44:00 +08:00
    代码工作正常,没有性能问题爱怎么写怎么写,并无不妥

    你觉得高级的做法也并不是最佳实践,就算改了,重构后效果和重构前差不多,没啥用

    除非,你趁机牵头搞一个公司内部的服务调度框架 /中台 /平台,那还不错
    ForkNMB
        47
    ForkNMB  
       2021-12-01 12:07:27 +08:00
    不是 。定时任务为啥要用 Spring 自带的,贼不好用,为啥不用 XXLJOB
    BBCCBB
        48
    BBCCBB  
       2021-12-01 12:14:25 +08:00
    4L 正解.
    jackzhengjbs
        49
    jackzhengjbs  
       2021-12-01 12:41:05 +08:00 via Android
    我是你领导,下班之后来我办公室,🐶头
    C603H6r18Q1mSP9N
        50
    C603H6r18Q1mSP9N  
       2021-12-01 13:52:16 +08:00
    正解:写个 内部请求地址,linux crontab 定时调用这个链接
    code4you
        51
    code4you  
       2021-12-01 14:10:40 +08:00   ❤️ 2
    性能优化

    以前 Thread.sleep(10000)

    优化 Thread.sleep(1000)

    再次优化 Thread.sleep(100)

    极度优化 Thread.sleep(10)

    😁
    corningsun
        52
    corningsun  
       2021-12-01 14:36:12 +08:00
    @shanghai1998 自己用着爽,运维火葬场。
    Jooooooooo
        53
    Jooooooooo  
       2021-12-01 14:55:59 +08:00
    sleep 当然不会消耗资源

    这当然也是也是一种定时任务的办法

    你领导说的不靠谱的现象确实存在, 要是异常没处理好, 定时任务可能就会没了
    Lemeng
        54
    Lemeng  
       2021-12-01 14:56:16 +08:00
    出问题,不用自己负责的事,不操心,呵呵
    zhuangzhuang1988
        55
    zhuangzhuang1988  
       2021-12-01 15:18:42 +08:00
    ligiggy
        56
    ligiggy  
       2021-12-01 16:10:12 +08:00
    @code4you 致富之路
    fangcan
        57
    fangcan  
       2021-12-01 17:18:30 +08:00
    可以发信息再找他确认下,留下证据
    yousabuk
        58
    yousabuk  
       2021-12-01 20:25:08 +08:00
    犟啥呢,已经出现对你的所有建议看都不看直接否定的情况了。

    小心了,对你有意见了已经。
    AlexRoot
        59
    AlexRoot  
       2021-12-01 21:33:14 +08:00
    @Aliberter 这种老大,建议跑路,感觉以后要背大锅。
    kaneg
        60
    kaneg  
       2021-12-01 22:22:28 +08:00
    sleep 是会一直占用当前线程,应该用 object 的 wait 方法。
    如果只是用定时,可以用 ScheduledExecutorService
    railgun
        61
    railgun  
       2021-12-01 22:53:03 +08:00
    符合业务需求就没有问题
    anonymous1024
        62
    anonymous1024  
       2021-12-01 23:39:08 +08:00
    如果当前操作系统是抢占式内核,在死循环中写 sleep 是可以放弃 cpu 占用时间的,提高其他程序的命中率。
    C603H6r18Q1mSP9N
        63
    C603H6r18Q1mSP9N  
       2021-12-02 10:43:24 +08:00
    正解:写个 内部请求地址,linux crontab 定时调用这个链接

    @corningsun 不会的,crontab 有运维管理的平台统一调度处理的
    goalidea
        64
    goalidea  
       2021-12-02 11:06:20 +08:00
    首先不考虑性能的话,能实现就行,其次 sleep 要考虑多线程的问题,毕竟是要抱着锁去睡觉
    olaloong
        65
    olaloong  
       2021-12-02 11:14:12 +08:00
    看具体用法吧....我有个 10 秒一次的定时任务就是循环+sleep ,无锁无竞争也不会有啥问题
    oOoOoOoOoOo
        66
    oOoOoOoOoOo  
       2021-12-02 15:51:35 +08:00 via Android
    @code4you

    等 sleep 语句删掉的时候:

    重新优化了代码结构,缩减了代码行数,提高了运行效率。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1780 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:44 · PVG 00:44 · LAX 08:44 · JFK 11:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.