Java 多线程进阶——并发安全、死锁与生产者消费者模型

  1. 为什么需要线程同步?

当多个线程同时修改同一个变量(例如银行账户余额)时,可能会发生“数据覆盖”或“读取脏数据”的情况。这就好比两个人同时去改同一份文档,如果不加锁,最后的结果肯定是一团糟。
为了解决这个问题,Java 提供了线程同步机制。

  1. 给代码加把锁:synchronized

synchronized是Java中最常用的同步关键字,它能保证同一时刻只有一个线程能执行被锁住的代码块。

同步方法:直接在方法声明上加  synchronized ,锁的是当前对象 ( this )。
同步代码块: synchronized(obj) { ... } ,锁的是括号里的对象  obj 。

原理:这就像上厕所,门上的锁就是  synchronized 。一个人进去了(获取锁),其他人只能在外面等(阻塞),直到里面的人出来(释放锁)。

  1. 警惕!多线程的噩梦——死锁

死锁是指两个或多个线程互相持有对方需要的资源,并且都在等待对方释放,导致所有线程都无法继续执行。

死锁产生的四个必要条件:

互斥条件:资源只能被一个线程占用。
请求与保持条件:占着碗里的,看着锅里的。
不剥夺条件:资源只能由持有者主动释放。
循环等待条件:A 等 B,B 等 A,形成闭环。

避免死锁最简单的方法是破坏“循环等待条件”,比如规定所有线程必须按照相同的顺序获取锁。

  1. 经典实战:生产者消费者模型

场景:有一个仓库(缓冲区),生产者负责生产产品放入仓库,消费者负责从仓库取走产品。

规则:
仓库满了,生产者必须停止生产(等待)。
仓库空了,消费者必须停止消费(等待)。
一旦有变动,需要通知对方。

核心方法配合:

wait() :线程进入等待状态,释放锁。
notify()  /  notifyAll() :唤醒正在等待的线程。

在这个模型中,我们通常使用  Object  类的  wait/notify  机制,或者使用更高级的  BlockingQueue (阻塞队列)来实现解耦。

posted @ 2026-06-05 23:09  定缘  阅读(21)  评论(0)    收藏  举报