synchronized代码块是否会交错执行?代码运行结果不符预期的疑问
为什么你的Java代码没出现预期的死锁?
你核心的误解点在于对synchronized (this)中this的指向判断错误——你以为两个线程的同步块锁的是同一个对象,但实际上它们锁的是完全独立的两个实例!
先拆解你的代码里的锁对象:
你的reader和writer是两个独立的匿名Runnable内部类实例:
reader的synchronized (this),锁的是这个readerRunnable对象本身writer的synchronized (this),锁的是这个writerRunnable对象本身
这意味着两个线程的同步块根本不会互相阻塞!writer线程完全不需要等待reader释放任何锁,它可以直接进入自己的同步块修改condition变量,这就是为什么你会看到代码正常执行完的输出:
waiting for condition condition is set to true condition is true
你预想的死锁场景怎么才会发生?
如果要让两个线程竞争同一个锁,你需要把同步块的锁对象改成同一个,比如锁Test类的实例(也就是外部类对象):
// reader的同步块改成锁Test.this synchronized (Test.this) { System.out.println("waiting for condition"); while (!condition) {} System.out.println("condition is true"); } // writer的同步块也改成锁Test.this synchronized (Test.this) { System.out.println("condition is set to true"); condition = true; }
这时候如果reader线程先拿到Test.this的锁,进入死循环,writer线程就会一直等待锁释放,才会出现你预想的死锁情况。
额外提个小问题:关于condition的可见性
你的condition是静态变量,虽然这里巧合能让reader看到writer的修改,但如果是非静态变量,且没有同步在同一个锁上,会存在线程可见性问题——reader可能永远看不到writer修改后的condition值。正确的做法是要么用synchronized同步同一个锁,要么把condition声明为volatile,来保证变量的跨线程可见性。
内容的提问来源于stack exchange,提问作者blue note
相关产品推荐
相关产品推荐

