当前位置: 首页 > 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.jsqmd.com/news/984833/

相关文章:

  • logo设计大赛/服务明星评选微信投票小程序怎么做?这5个坑90%的人都在踩|众星评选避坑指南 - 微信投票小程序
  • 2026年6月拖地机厂家推荐排行榜:手推式/驾驶式/自走式/电瓶式拖地机,全自动拖地车源头厂家深度解析 - 企业推荐官【官方】
  • 下水管道爬行检测机器人品牌推荐 - 资讯焦点
  • 温州洞头区商圈实测:当前金价与回收避坑指南 - 专业黄金回收
  • 广州白云区厂区园区排污运维工程|化粪池清理抽粪隔油池清洗管道高压清洗|下水道疏通管道改管一站式施工 - 天堂海洋
  • Elastic Agent独立模式避坑指南:从API密钥权限到服务启动的完整配置流程
  • 2026聚焦工业与市政清洁:高压清洗机厂家评估与选择策略 - 企业推荐官【官方】
  • 手把手教你用MATLAB复现圆柱绕流POD分解(附Brunton案例完整代码与避坑指南)
  • 图片翻译工具测评:几款主流产品的功能对比与选择建议
  • 2026年实测免费图片格式转换软件?图片拼图压缩加水印全搞定 - 热点速览
  • 慈溪黄金回收行情播报 结合6月金价走势谈黄金变现技巧 - 润富黄金回收
  • 文科生零基础不会编程,为什么也要重视人工智能应用?
  • 太阳能球场灯选购指南:如何科学选择合适产品 - 热点速览
  • AutoCAD2016经典模式不见了-设置回14版本前的经典工作空间
  • 2026绍兴防水补漏哪家靠谱?正规公司排名及避坑价格指南 - 苏易修缮
  • CAPL脚本里,你的变量真的‘听话’吗?聊聊局部变量的‘记忆’特性
  • 2026 美国配电展:硬核展台展览,优质设计搭建公司焕新推荐 - 资讯焦点
  • Web应用开发入门与实战总结
  • 青岛管道漏水检测哪家好?消防管道测漏 /TOP5 公司推荐,精准定位无盲拆,避坑不踩雷 - 速递信息
  • 合肥市消防管无声漏水检测,长期慢漏暗漏,仪器深度扫描排查--2026年室外消防管漏水检测维修公司top推荐热榜 - 同城资讯
  • 杭州富阳区通下水通马桶地漏,菜池厨房下水,打捞异物卫生间除臭--2026杭州疏通top排行榜推荐公司 - 同城资讯
  • 用Cesium打造酷炫三维大屏:动态飞线、雷达扫描与天气特效的完整配置流程
  • 别再只画流线图了!用POD模态分解为你的CFD结果做一次“CT扫描”
  • 2026年四川首选白酒加盟品牌优选参考,不容错过! - 企业推荐官
  • openfeign如何获取远程调用接口上的url地址
  • 广元黄金回收2026大盘价当面结算无套路 - 润富黄金回收
  • 2026菏泽黄金回收全攻略 六家门店横向评测附地址 - 余生黄金回收
  • 珠三角五金冲压件工厂选购指南:如何选到靠谱合作伙伴 - 热点速览
  • 2026锦州乡镇城区黄金回收避坑指南 多家正规门店综合测评 - 余生黄金回收
  • 别再只用加减乘除了!用Python的math和operator库,一行代码搞定M和N的5种运算