最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Java 中继承 Thread 类后如何正确实现线程同步
时间:2026-07-28 07:07:59 编辑:袖梨 来源:一聚教程网
继承Thread类实现线程同步需共用同一锁对象,共享资源必须static,优先用synchronized代码块锁定关键语句,避免锁this或非static方法,并妥善处理中断异常。
继承 Thread 类后实现线程同步,核心在于**确保多个线程对共享资源的访问是串行化的**。由于每个 Thread 子类实例默认拥有独立的锁(this),若不统一同步监视器,synchronized 方法或代码块将无法真正互斥——这是初学者最常踩的坑。
必须用同一个对象作为同步监视器
继承 Thread 时,每个线程对象都是独立实例,synchronized 实例方法锁的是各自对象(this),相当于每人一把锁,起不到同步效果。正确做法是让所有线程共用一个锁对象:
- 把共享资源和锁声明为
static,例如private static final Object LOCK = new Object(); - 或在构造时传入同一个外部对象(如主类实例、单例工具类)作为锁
- 避免直接用
this或Thread.currentThread()做锁,它们对每个线程都不一样
推荐使用 synchronized 代码块而非同步方法
同步方法会锁住整个 run() 执行过程,粒度太粗,影响并发效率。更合理的是只锁定真正操作共享资源的那一小段:
- 写法示例:
synchronized (LOCK) { num--; } - 锁内只放读写共享变量、修改状态等关键语句,不要包含
sleep()、IO 或耗时逻辑 - 如果必须用同步方法,需确保它是
static的(锁Class对象),否则仍无效
共享资源必须声明为 static
模拟卖票、计数器等场景时,票数、计数器等变量必须用 static 修饰:
立即学习“Java免费学习笔记(深入)”;
- 非
static字段属于每个线程实例,彼此隔离,根本不存在竞争 -
static才能让所有线程看到同一份数据,同步才有意义 - 配合
volatile可解决可见性问题(如状态标志),但不能替代同步解决原子性
注意异常处理与中断响应
在同步块内调用 sleep() 或 wait() 时,可能抛出 InterruptedException:
- 不能简单
e.printStackTrace()后吞掉异常,应恢复中断状态:Thread.currentThread().interrupt(); - 同步块中发生异常,要确保锁能正常释放(Java 自动保证,无需手动 unlock)
- 避免在同步块里做可能长时间阻塞的操作,防止其他线程无限等待