Java多线程初阶完整总结|线程、锁、volatile、等待通知、常见案例
一、认识线程1. 什么是线程线程就是一条独立执行流多个线程可以同时执行多份代码。 进程是资源分配的最小单位线程是CPU调度的最小单位。一个进程至少包含1个主线程同一个进程内多个线程共享堆、方法区内存每个线程私有虚拟机栈、本地方法栈、程序计数器进程之间内存相互隔离一个线程崩溃会导致整个进程崩溃。为什么用线程充分利用多核CPU算力IO等待时可以执行其他任务提升程序整体效率相比进程线程创建、销毁、调度开销更小。2. Java创建线程的4种写法继承Thread类重写run()调用start()启动线程class MyThread extends Thread { Override public void run() { System.out.println(线程执行); } } // 使用 MyThread t new MyThread(); t.start();实现Runnable接口传入Thread构造器class MyRunnable implements Runnable{ Override public void run() { System.out.println(runnable执行); } } Thread t new Thread(new MyRunnable()); t.start();匿名内部类ThreadThread t new Thread(){ Override public void run() {} };Lambda表达式推荐代码简洁Thread t new Thread(() - { System.out.println(lambda线程); }); t.start();⚠️注意run()只是普通方法start()才会向操作系统申请创建真正的线程。3. Thread常用属性与方法API说明getId()线程唯一idgetName()获取线程名字getState()获取线程状态getPriority()获取优先级优先级高只是更容易被调度不代表一定先执行isDaemon()是否后台守护线程JVM等待所有非后台线程结束才退出isAlive()线程是否存活不是NEW、不是TERMINATED即为存活interrupt()中断线程设置中断标记如果线程阻塞(sleep/wait)会抛出InterruptedException并清除标记currentThread()静态方法获取当前正在执行的线程对象sleep(ms)休眠线程不会释放锁实际休眠时间≥设置时间受操作系统调度影响join()等待其他线程执行完毕支持设置最大等待时间中断线程两种方式自定义volatile布尔标记位循环判断标记退出interrupt()isInterrupted()/Thread.interrupted()。interrupted()读取中断标记同时清除标记isInterrupted()只读取不清除标记。二、线程的6种状态与流转线程状态是枚举Thread.State一共6种NEW线程对象创建还没调用start()RUNNABLE就绪/运行中代表线程可以被CPU调度执行不一定正在跑CPUBLOCKED等待获取synchronized锁锁被别的线程占有阻塞排队WAITING无限等待等待其他线程唤醒wait()、join()、park()TIMED_WAITING限时等待超时自动唤醒sleep()、wait(time)TERMINATED线程执行完毕区分BLOCKED抢锁失败等锁WAITING / TIMED_WAITING主动放弃CPU等待其他线程通知或者超时。三、线程安全定义多线程环境下程序运行结果和单线程预期结果一致就是线程安全。线程不安全的4个根源线程抢占式随机调度操作系统随时切换线程执行顺序不可预测修改共享变量多个线程同时读写同一个内存变量不具备原子性一条Java代码可能对应多条CPU指令执行中途会被打断。 例如count分为三步读内存 → CPU计算 → 写回内存多线程并发会出现数据丢失内存可见性问题JMM Java内存模型线程拥有自己的工作内存CPU缓存/寄存器修改先写副本不一定立刻刷入主内存其他线程看不到最新值指令重排序编译器、CPU为性能对指令进行重排单线程逻辑不变多线程下会出现异常。Java内存模型 JMM主内存真正物理内存存放共享变量工作内存每个线程私有对应CPU寄存器、高速缓存是变量副本。 线程读写共享变量都是操作工作内存再同步主内存会带来可见性bug。四、synchronized 监视器锁synchronized是Java内置的悲观锁基于操作系统mutex实现。三大特性互斥原子性同一时间只允许一个线程进入同步块。进入加锁退出解锁竞争失败线程进入阻塞队列BLOCKED。可重入同一个线程可以重复获取同一把锁内部维护锁持有者计数器计数器归0才释放锁避免自己把自己锁死。保证可见性、禁止指令重排序。四种写法锁普通对象代码块synchronized(对象){}锁当前对象thissynchronized(this){}修饰普通方法锁当前实例对象public synchronized void test(){}修饰静态方法锁类对象.classpublic static synchronized void test(){}关键点只有竞争同一对象锁才会阻塞不同对象互不干扰。JDK线程安全/不安全类❌线程不安全ArrayList、HashMap、HashSet、StringBuilder✅线程安全StringBuffer、Vector、HashTable不推荐、ConcurrentHashMapString不可变天生线程安全。五、volatile关键字作用保证变量内存可见性禁止指令重排序不保证原子性。写volatile变量修改工作内存副本强制刷新到主内存读volatile变量强制从主内存读取最新值不使用缓存副本。注意volatile int count不能解决count线程不安全因为不是原子操作。使用场景多线程下一个线程写、多个线程读的标记变量。六、wait / notify / notifyAll属于Object的方法用来做线程之间的协作通信控制线程执行顺序。wait()当前线程释放锁进入对象等待队列等待被唤醒、超时、被interrupt必须写在synchronized同步块内部否则抛异常。notify()唤醒该对象等待队列中随机一个线程不会立刻释放锁退出同步代码块之后锁才释放。notifyAll()唤醒该对象等待队列全部等待线程唤醒后所有线程需要重新竞争锁。wait vs sleep对比waitsleep归属Object方法Thread静态方法锁必须在synchronized内调用调用后释放锁不需要锁休眠不释放锁用途线程间通信协作单纯让线程休眠一段时间最佳实践wait()要写在while循环里面防止虚假唤醒。七、多线程经典案例案例1单例模式饿汉模式类加载直接创建实例天然线程安全class Singleton{ private static Singleton instance new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; } }懒汉模式双重检查锁DCLclass Singleton{ // volatile禁止指令重排序防止半初始化对象 private static volatile Singleton instance; private Singleton(){} public static Singleton getInstance(){ if(instance null){ //外层判断减少锁竞争 synchronized (Singleton.class){ if(instance null){ instance new Singleton(); } } } return instance; } }volatile作用阻止new Singleton()指令重排避免其他线程拿到未初始化完成的对象。案例2阻塞队列 生产者消费者模型阻塞队列特性队列满时入队put()阻塞队列空时出队take()阻塞。生产者‑消费者模型作用解耦生产者、消费者不直接交互通过队列通信削峰填谷缓冲流量平衡生产和消费速度防止瞬时流量打垮服务。标准实现LinkedBlockingQueueput()入队take()阻塞取出。简易实现思路数组存储元素synchronizedwait/notifyAllput满就waittake空就wait。案例3定时器TimerJDK提供Timerschedule(task,delay)延迟执行任务。简易定时器实现优先队列存放定时任务后台线程循环扫描队首任务时间到执行任务。案例4线程池频繁创建销毁线程开销高线程池复用已有线程。 核心组成核心线程数、最大线程数、阻塞队列、空闲存活时间、拒绝策略。Executors工具快速创建线程池newFixedThreadPool(n)固定线程数newCachedThreadPool()动态扩容newSingleThreadExecutor()单线程池四种拒绝策略AbortPolicy直接抛异常默认CallerRunsPolicy调用者线程自己执行任务DiscardOldestPolicy丢弃队列最老任务DiscardPolicy直接丢弃新任务不抛异常八、保证线程安全的整体思路不使用共享变量共享变量只读使用不可变对象修改共享变量时保证原子性、可见性、有序性原子性synchronized、锁、CAS可见性volatile、锁有序性volatile、锁禁止重排序。结尾小结多线程核心难点在于理解抢占调度带来执行顺序不可控引出原子性、可见性、重排序三类问题。synchronized悲观锁保证原子可见有序会阻塞volatile只解决可见性与重排序不能保证原子性wait‑notify做线程通信业务优先使用线程池不要手动频繁new Thread。

相关新闻

数据安全到底怎么做?权限、脱敏、水印、防泄漏、审计全讲明白

数据安全到底怎么做?权限、脱敏、水印、防泄漏、审计全讲明白

很多企业一提数据安全,第一反应都是:把权限管严一点。财务只能看财务数据,销售只能看销售数据,核心报表只给管理层开放。但真正做过数据平台以后就会发现,数据安全远比“谁能看”复杂。一个销售经理有权限查看客户数据…

2026/10/17 11:16:09 阅读更多 →
同城快递平台源码:独立部署+实时查件+CPs分佣一体化解决方案

同城快递平台源码:独立部署+实时查件+CPs分佣一体化解决方案

简介:同城快递平台是面向区县与社区的本地化履约中台,融合即时配送、地理围栏调度与快递状态语义解析等核心技术,实现低延迟查件与高并发调度。其技术价值在于将高频快递查询行为转化为本地服务流量入口,支撑cps分佣、流量主变现与…

2026/10/2 21:44:31 阅读更多 →
经营分析和财务分析有什么区别?财务人看懂生意的第一道坎,一文讲清!

经营分析和财务分析有什么区别?财务人看懂生意的第一道坎,一文讲清!

很多财务人都会经历一个阶段: 利润表已经看得很熟,但一旦领导追问“为什么利润下降”“哪个客户出了问题”“这块业务到底还值不值得继续投”,分析就容易卡住。 不是不会算指标,而是分析仍然停留在财务结果,没有真正…

2026/11/1 21:18:59 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/6 15:21:35 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/6 9:29:27 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/6 22:01:11 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/6 22:01:11 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/6 8:08:42 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/6 22:01:09 阅读更多 →

日新闻

周新闻

月新闻