You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于实体ID的Java ReentrantLock同实体更新互斥实现需求

基于实体ID的可重入锁实现方案

你需要的是按实体ID维度隔离的锁管理器,核心思路是用并发容器维护每个ID对应的可重入锁,保证同一ID的操作互斥,不同ID的操作并行。以下是具体实现:

1. 锁管理器核心实现

创建单例锁管理类,用ConcurrentHashMap存储实体ID与锁的映射,同时通过引用计数避免内存泄漏:

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

public class EntityLockManager {
    private static final EntityLockManager INSTANCE = new EntityLockManager();
    private final ConcurrentHashMap<String, LockWrapper> lockMap = new ConcurrentHashMap<>();

    private EntityLockManager() {}

    public static EntityLockManager getInstance() {
        return INSTANCE;
    }

    // 获取对应实体ID的锁
    public ReentrantLock getLock(String entityId) {
        lockMap.compute(entityId, (id, wrapper) -> {
            if (wrapper == null) {
                return new LockWrapper(new ReentrantLock());
            }
            wrapper.incrementRefCount();
            return wrapper;
        });
        return lockMap.get(entityId).lock;
    }

    // 释放对应实体ID的锁
    public void releaseLock(String entityId) {
        lockMap.computeIfPresent(entityId, (id, wrapper) -> {
            wrapper.decrementRefCount();
            return wrapper.getRefCount() == 0 ? null : wrapper;
        });
    }

    // 内部类:封装锁和引用计数
    private static class LockWrapper {
        private final ReentrantLock lock;
        private int refCount;

        public LockWrapper(ReentrantLock lock) {
            this.lock = lock;
            this.refCount = 1;
        }

        public void incrementRefCount() {
            refCount++;
        }

        public void decrementRefCount() {
            refCount--;
        }

        public int getRefCount() {
            return refCount;
        }
    }
}

2. 业务代码中的使用方式

在批量更新逻辑中,捕获OptimisticLockException后,获取对应ID的锁并重试操作:

public void updateEntity(String entityId, Entity entity) {
    boolean success = false;
    while (!success) {
        try {
            // 先尝试乐观锁更新
            entityRepository.save(entity);
            success = true;
        } catch (OptimisticLockException e) {
            // 乐观锁冲突时,获取对应ID的锁
            ReentrantLock lock = EntityLockManager.getInstance().getLock(entityId);
            try {
                lock.lock();
                // 加锁后查询实体最新状态,执行更新
                Entity latestEntity = entityRepository.findById(entityId).orElseThrow();
                mergeEntityUpdates(latestEntity, entity);
                entityRepository.save(latestEntity);
                success = true;
            } finally {
                lock.unlock();
                EntityLockManager.getInstance().releaseLock(entityId);
            }
        }
    }
}

// 合并实体更新逻辑(根据业务调整)
private void mergeEntityUpdates(Entity target, Entity source) {
    target.setField1(source.getField1());
    target.setField2(source.getField2());
    // 其他字段更新...
}

关键注意事项

  • 重入性支持:基于ReentrantLock,同一线程多次获取同一ID的锁不会阻塞,适配嵌套调用场景。
  • 内存泄漏防护:通过引用计数,当某ID的所有锁释放后,会从容器中移除对应条目,避免长期占用内存。
  • 性能优化:仅在乐观锁冲突时加锁,无冲突的更新仍可并行执行,不影响批量处理效率。
  • 锁粒度精准:严格按实体ID隔离,不同ID的操作完全并行,最大化利用系统资源。

内容的提问来源于stack exchange,提问作者Cliser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 11:16:14