当前位置: 首页 > news >正文

JUC 概述

并发,并行,串行

  • 并发:宏观上同时进行,微观上交替切换执行,单个 CPU 核心,靠快速切换任务
  • 并行:同一时刻,多个任务真正同时运行,多个 CPU 核心,每个核心独立跑一个任务
  • 串行:同一时刻只做一件事,做完一件再做下一件

线程

什么是线程

一个程序运行时,内部可以分成一个或多个线程,线程是CPU 执行任务的最小单位

创建线程的方式

实现 Runnable

classMyRunnableimplementsRunnable{@Overridepublicvoidrun(){System.out.println("Runnable 线程:"+Thread.currentThread().getName());}}publicclassTest{publicstaticvoidmain(String[]args){MyRunnabler=newMyRunnable();Threadt=newThread(r);t.start();}}

继承 Thread

classMyThreadextendsThread{@Overridepublicvoidrun(){System.out.println("线程运行:"+Thread.currentThread().getName());}}publicclassTest{publicstaticvoidmain(String[]args){MyThreadt=newMyThread();t.start();// 启动线程}}

实现 Callable

classMyCallableimplementsCallable<Integer>{@OverridepublicIntegercall()throwsException{System.out.println("Callable 线程运行");return100;// 可以返回结果}}publicclassTest{publicstaticvoidmain(String[]args)throwsException{FutureTask<Integer>task=newFutureTask<>(newMyCallable());Threadt=newThread(task);t.start();// 获取返回值Integerres=task.get();System.out.println("结果:"+res);}}

线程池创建

publicclassTest{publicstaticvoidmain(String[]args){// 创建线程池ExecutorServicepool=Executors.newFixedThreadPool(3);// 提交任务pool.submit(()->{System.out.println("线程池线程:"+Thread.currentThread().getName());});pool.shutdown();// 关闭线程池}}

线程的生命周期

  1. 新建,创建了一个线程对象,但是没有调用 start() 方法
  2. 就绪,调用了 start(),等着 CPU 分配时间片,一旦拿到 CPU,就开始执行 run()
  3. 阻塞,线程阻塞于锁
  4. 等待,主动无限期等别人唤醒,例如:wait() / join() / LockSupport.park()
  5. 定时等待,有时间限制的等待,例如:sleep(1000) / wait(1000) / join(1000)
  6. 终止,run() 执行完 / 异常退出

状态的流转关系

NEW → start() → RUNNABLE RUNNABLE ↓ 抢锁失败 BLOCKED → 拿到锁 → RUNNABLE RUNNABLE ↓ wait()/join() WAITING → notify()/notifyAll() → RUNNABLE RUNNABLE ↓ sleep(1000) TIMED_WAITING → 时间到 → RUNNABLE RUNNABLE → 执行完毕 → TERMINATED

如何终止线程

stop

强制杀死线程,已弃用

interrupt
publicclassTest{publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt=newThread(()->{try{while(!Thread.currentThread().isInterrupted()){System.out.println("运行中...");Thread.sleep(1000);}}catch(InterruptedExceptione){// 收到中断信号,退出System.out.println("线程被中断终止");}});t.start();Thread.sleep(2000);t.interrupt();// 中断}}
interrupt()、interrupted()、isInterrupted()的作用以及区别
  1. thread.interrupt()
    作用:中断线程(设置 interupted = true)
    类型:实例方法
    效果:
    如果线程正在运行:仅设置中断标志,不停止运行
    如果线程在 sleep()/wait()/join():会抛出 InterruptedException,并清除中断标志
    不会强制停止线程,只是通知

  2. thread.isInterrupted()
    作用:查询是否被中断
    类型:实例方法
    特点:
    只读取,不改变状态
    调用一次,标记依然保留

  3. Thread.interrupted()
    作用:查询 + 清除中断标记
    类型:静态方法
    特点:
    第一次调用返回 true
    第二次调用一定返回 false(因为复位了)
    只针对当前执行的线程,例如在 main 线程中执行 t1.interrupted(),其实查询的是 main 线程的 interupted 变量并复位

synchronized

锁升级

无锁 → 偏向锁 → 轻量级锁 → 重量级锁

单向升级,不可降级,只有释放锁后才会变回无锁

无锁

默认的无锁状态

偏向锁(jdk 15+ 默认取消偏向锁)

锁一直被同一个线程拿

第一次抢锁:CAS 把当前线程 ID 写入对象头,之后再来,只要线程 ID 匹配,直接进,不需要 CAS

第二个线程来竞争时,偏向锁被撤销 → 升级轻量级锁

轻量级锁

两个线程交替用锁,无长时间阻塞

参考

线程在自己的栈帧创建 Lock Record,把对象头复制到 Lock Record 中,通过 CAS 把对象头换成指向自己 Lock Record 的指针

成功:拿到锁

失败:将锁升级为重量级锁,然后进入 cxq 链表进行自旋,自旋成功则获取锁,自旋多次失败则会进入阻塞状态,等待唤醒

重量级锁

monitor-enter

每一个对象都会和一个监视器monitor关联, 监视器被占用时会被锁住, 其他线程无法来获取该监视器, 当JVM执行某个对象的 monitorenter(synchronized(obj)) 方法时, 会尝试去获取对象的监视器所有权, 过程如下:

  1. 如果monitor 的进入数为 0, 则线程可以进入monitor, 并将 monitor 的进入数变为 1, 当前线程成为 monitor 的所有者
  2. 如果线程已经拥有了 monitor 的所有权, 允许重入 monitor, 此时 monitor 的进入数 +1
  3. 如果其他线程已经占有了 monitor, 当前线程尝试获取 monitor 所有权时会被阻塞, 直到 monitor 的进入数为 0
monitor-exit
  1. 能执行monitorexit指令的线程一定是拥有monitor所有权的线程
  2. 执行monitorexit指令后, monitor 的进入数 -1, 当进入数变为 0 后, 表示当前线程释放锁, 不再拥有 monitor 的所有权, 此时其他阻塞的线程可以去尝试获取monitor的所有权

synchronized 执行时, 没有竞争到锁的线程会被挂起, 此时需要调用操作系统的park() 方法, 竞争到锁的线程会被 unpark() 唤醒

http://www.gsyq.cn/news/1496577.html

相关文章:

  • 屏蔽多云差异:多云底座的架构设计与实践
  • 温州洞头区商圈实测:当前金价与回收避坑指南 - 专业黄金回收
  • 下水管道爬行检测机器人品牌推荐 - 资讯焦点
  • 文科生零基础不会编程,为什么也要重视人工智能应用?
  • 2026绍兴防水补漏哪家靠谱?正规公司排名及避坑价格指南 - 苏易修缮
  • 2026年实测免费图片格式转换软件?图片拼图压缩加水印全搞定 - 热点速览
  • 杭州富阳区通下水通马桶地漏,菜池厨房下水,打捞异物卫生间除臭--2026杭州疏通top排行榜推荐公司 - 同城资讯
  • 2026年四川首选白酒加盟品牌优选参考,不容错过! - 企业推荐官
  • 合肥市消防管无声漏水检测,长期慢漏暗漏,仪器深度扫描排查--2026年室外消防管漏水检测维修公司top推荐热榜 - 同城资讯
  • 广元黄金回收2026大盘价当面结算无套路 - 润富黄金回收
  • UVM验证进阶:拆解start_item源码,搞懂sequencer参数怎么用才高效
  • 合肥市大型园区消防管道测漏公司,地埋管网渗漏精准探测,全天候上门服务电话-消防漏水检测top推荐公司 - 同城资讯
  • 林地全自动拓荒机2026年|选源头厂家还是中间商? - 博客万
  • 从硬件总线视角看TriCore多核锁:TC264的CMPSWAP.W指令如何避免抢锁冲突
  • 2026 长治厨卫屋面地下室漏水瓷砖空鼓测评:吉修匠 99.8 分五星榜首 - 吉修匠
  • 2026年乐平管道疏通推荐指南:从家庭到商铺全场景覆盖 实体团队专业设备省心选择 - 本地品牌推荐
  • 现场写作/最美笔记/英文书写大赛投票怎么一键生成?微信小程序免费测评|众星评选实测推荐 - 微信投票小程序
  • 2026年主流粮食烘干机厂家品牌解析及选购指南 - 博客万
  • 吉安泰和县房屋漏水检测上门服务 卫生间厨房阳台地暖水管精准查漏水 - 同城资讯
  • 别再只用加减乘除了!用Python的math和内置函数,解锁M和N的5种高级运算
  • 场景下接线端子品牌排名怎么选:五家主流品牌深度测评 - 热点速览
  • 2026衡阳市黄金回收全攻略 六家实体门店横向评测附地址避坑指南 - 余生黄金回收
  • 生信分析避坑指南:你的多序列比对为什么总失败?从序列准备到工具选择的5个常见错误
  • VMware Horizon连接服务器证书报错?手把手教你用域控CA证书搞定它
  • 从开发者视角看数据泄露:那些年我们无意中留下的‘社工库’入口
  • 2026揭阳市黄金回收全攻略 多家实体门店横向评测附地址避坑指南 - 余生黄金回收
  • 别再被低价忽悠!等速万向节专机选购建议:看这5点,质量售后全搞定 - 品牌推荐大师
  • 锦州市专业消防管,供暖管、自来水管漏水检测、外网埋地管道测漏、无损定位 - 天堂海洋
  • 2026年成都回头客多的打酒铺,5强实力榜单为你揭秘! - 企业推荐官
  • LOGO设计大赛服务明星评选投票怎么免费做?企业校园通用投票制作教程(强防刷+零广告+数据免费导) - 微信投票小程序