多线程共享AtomicLong:能否将递减while循环移出锁范围?
关于ReentrantLock同步下AtomicLong递减循环位置的疑问
现有两个线程共享一个AtomicLong实例,线程1仅执行递增操作,线程2仅执行递减操作,使用ReentrantLock和Condition实现线程同步。相关共享变量及线程代码如下:
final var lock = new ReentrantLock(); final var condition = lock.newCondition(); final var accumulated = new AtomicLong(); // accumulated <n> from <request(n)>
线程1代码:
// Thread 1 void doSome(final long n) { try { lock.lock(); if (accumulated.addAndGet(n) < 0L) { // overflowed accumulated.set(Long.MAX_VALUE); // > effectively unbounded } condition.signal(); } finally { lock.unlock(); } }
线程2代码:
// Thread 2 while (!Thread.currentThread().isInterrupted()) { lock.lock(); try { while (accumulated.get() == 0L) { try { condition.await(); } catch (final InterruptedException ie) { log.info("interrupted while awaiting the condition", ie); Thread.currentThread().interrupt(); break; } } while (accumulated.getAndDecrement() > 0L) { // - // do some // | } // | // | } finally { // | lock.unlock(); // | } // | // | // | //while (accumulated.getAndDecrement() > 0L) { // <-- Can(Should) I move the while loop to here? // // do some // } }
咨询问题:是否可以将线程2中用于递减AtomicLong的while循环移到锁代码块之外?
回答
不能将该while循环移到锁代码块之外,原因如下:
破坏原同步逻辑的原子性
线程1的递增操作是在lock的保护下执行的,原逻辑中线程2持有锁时,线程1无法修改accumulated,因此线程2可以安全地将当前累积值一次性递减到0。如果把循环移到锁外,线程2释放锁后,线程1会立即执行递增操作,导致线程2的递减循环会同时处理后续新增的值,违背了“被唤醒后处理当前累积值”的设计意图。多线程场景下引发竞态问题
如果存在多个线程2实例,移到锁外后,多个线程会同时执行getAndDecrement操作。虽然该方法本身是原子的,但会导致多个线程同时进入// do some逻辑,可能引发业务逻辑混乱或数据不一致——原代码通过独占锁保证了同一时间只有一个线程在处理递减逻辑。锁持有时间优化的替代方案
如果想减少锁的持有时间以提升性能,可以修改逻辑:在锁内获取当前累积值并重置为0,再释放锁,之后在锁外循环处理对应次数的业务逻辑。示例代码如下:// Thread 2 修改后的代码 while (!Thread.currentThread().isInterrupted()) { long count = 0; lock.lock(); try { while (accumulated.get() == 0L) { try { condition.await(); } catch (final InterruptedException ie) { log.info("interrupted while awaiting the condition", ie); Thread.currentThread().interrupt(); break; } } // 获取当前累积值并重置为0 count = accumulated.getAndSet(0L); } finally { lock.unlock(); } // 在锁外处理业务逻辑 while (count-- > 0) { // do some } }
内容的提问来源于stack exchange,提问作者Jin Kwon
相关产品推荐
相关产品推荐

