关于 Java 线程的疑惑 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MakHoCheung
V2EX    问与答

关于 Java 线程的疑惑

  •  
  •   MakHoCheung 2021-06-24 20:30:31 +08:00 1866 次点击
    这是一个创建于 1571 天前的主题,其中的信息可能已经有所发展或是发生改变。
    1. 什么是线程上下文切换呢,指的是就绪状态(没分到时间片)转到运行状态(分到时间片)或者调转过来这样子吗
    2. 线程切换需要用户态切换到内核态吗
    3. 自旋锁情况下,抢占的线程自旋过程是一直在运行状态吗(分到时间片)
    4. 我看书说到线程竞争重量级锁时候抢占不成功就从 Runnable (就绪或者运行状态)状态转阻塞状态,此时需要用户态切换到内核态来转状态,这时候就会有开销

    第 4 点我不怎么疑惑,毕竟书本说了,但是自旋会不会失去时间片呢,会不会也要用户态切换内核态呢,如果会的话自旋锁也逃避不了重量级锁的开销啊?

    希望 v 站大佬可以指教一下小弟

    9 条回复    2021-06-25 09:00:13 +08:00
    MakHoCheung
        1
    MakHoCheung  
    OP
       2021-06-24 21:44:25 +08:00
    https://blog.51cto.com/u_15064655/2573032 这个已经解答了我的问题
    tame619
        2
    tame619  
       2021-06-24 22:31:24 +08:00 via iPhone
    自旋锁占用 cpu,只要系统分配到时间片,不超过次数就在自旋。超过了次数就升级。
    MakHoCheung
        3
    MakHoCheung  
    OP
       2021-06-24 22:48:10 +08:00
    @tame619 自旋线程被调度就有开销了,所以自旋锁的情况下线程一般少于 cpu 的核数,这就是我看书说的竞争不激烈的情况下自旋锁有优势。你说的这是自旋锁怎么膨胀
    tame619
        4
    tame619  
       2021-06-24 23:00:15 +08:00 via iPhone
    @MakHoCheung 不是。线程上下文切换有开销,
    如果一个同步块只要 0.01ms 解决,还不如牺牲 cpu 自旋。减少上下文切换
    MakHoCheung
        5
    MakHoCheung  
    OP
       2021-06-24 23:07:13 +08:00
    @tame619 是啊,我刚刚说了“自旋线程被调度就有开销了”,我一开始不清楚这个,看了上面文章 这个就懂了,线程切换有开销
    MakHoCheung
        6
    MakHoCheung  
    OP
       2021-06-24 23:08:21 +08:00
    @tame619 你说的这个也对
    billlee
        7
    billlee  
       2021-06-25 01:16:55 +08:00
    线程上下文切换指某个 CPU 核心从运行一个线程变为运行另一个线程,显然是需要进入内核态的
    GeruzoniAnsasu
        8
    GeruzoniAnsasu  
       2021-06-25 08:19:29 +08:00   2
    1. 线程是一个操作系统机制,不是语言机制。是“java 做了什么去适配线程机制”,而不是“java 怎么去实现线程机制”,这里的先后因果是不一样的。我发现其实有非常多人都不理解这个前提。

    2. 先从单核多任务开始理解,显然任何语言的实现都无法提供一个强行从当前运行着的代码中断并跳到其它线程执行其它代码的非主动方法,所以这个切换一定是由硬件实现的(时钟中断)。所以这种线程切换必定要进入内核(用户态不处理硬件中断)。由于两个线程中的代码和变量都不一样,所以切过去时要保存 /恢复执行现场,所谓上下文
    3. 当有两个线程共享一个资源并且要保证先后顺序的时候,自然而然的想法就是第一个线程把自己该干的活干完,然后主动告诉内核我干完了,让另一个线程继续干。这就是所谓的“等待”,本质上是主动交出执行权。

    3. 进入多核时代,真并行任务开始变得普遍(以前也有多 CPU 架构,但基本与民用无关),从现在开始 CPU 可以同时执行多个线程,意味着切换上下文不再是必须的,多线程运行不一定会发生上下文切换。
    4. 自旋锁解决的就是并行架构下两个线程各自执行时怎么保证数据一致的问题:让某一个线程自我循环等待另一个线程出结果。由于并行化,一个线程忙等也不会阻碍其它线程继续执行,所以在忙等效率比较高的情况下就让它忙等无妨,这是所谓自旋的“等待”,本质上是循环检查

    5. 理解上述之后,给你一个要等待比如 1s 钟的锁,这么长时间对 cpu 来说显然是极大的浪费。所以虽然自旋也不影响其它线程,但还是让这个等待线程交出时间片先让其它线程来跑比较好,所以交出执行权还是循环检查这两种方式会看情况使用



    现代多核 cpu 的多线程机制讲完了,再看你的问题基本都覆盖了
    MakHoCheung
        9
    MakHoCheung  
    OP
       2021-06-25 09:00:13 +08:00
    @GeruzoniAnsasu 多谢,受教了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2803 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 00:28 PVG 08:28 LAX 17:28 JFK 20:28
    Do have faith in what you're doing.
    ubao 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