주석 추가, 패스워드변경 권한 수정

This commit is contained in:
2026-02-27 13:41:17 +09:00
parent ae4c1c61e8
commit dc42baf91a
13 changed files with 191 additions and 329 deletions

View File

@@ -7,19 +7,76 @@ import org.springframework.stereotype.Component;
@Component
public class ShpKeyLock {
/**
* key별 Lock 객체를 저장하는 맵
*
* <p>- key: 예) shp 파일 경로, uuid, 도엽번호 등 - value: 해당 key 전용 ReentrantLock
*
* <p>ConcurrentHashMap을 사용하여 멀티스레드 환경에서도 안전하게 접근 가능
*/
private final ConcurrentHashMap<String, ReentrantLock> locks = new ConcurrentHashMap<>();
/**
* 특정 key에 대한 Lock 시도
*
* @param key 동시성 제어 대상 식별자
* @return true → 락 획득 성공 false → 이미 다른 스레드가 사용 중
*/
public boolean tryLock(String key) {
/**
* computeIfAbsent 설명:
*
* <p>- 해당 key가 이미 존재하면 기존 Lock 반환 - 없으면 새 ReentrantLock 생성 후 저장
*
* <p>동시성 환경에서도 원자적으로 실행됨
*/
ReentrantLock lock = locks.computeIfAbsent(key, k -> new ReentrantLock());
/**
* tryLock():
*
* <p>- 대기하지 않고 즉시 시도 - 이미 다른 스레드가 점유 중이면 false 반환
*
* <p>→ 다운로드 중복 방지에 적합
*/
return lock.tryLock();
}
/**
* 특정 key에 대한 Lock 해제
*
* <p>반드시 tryLock 성공한 동일 스레드에서 호출해야 함
*/
public void unlock(String key) {
// 해당 key에 등록된 Lock 조회
ReentrantLock lock = locks.get(key);
/**
* isHeldByCurrentThread():
*
* <p>- 현재 스레드가 해당 락을 보유 중인지 확인 - 다른 스레드가 unlock 호출하는 것 방지
*/
if (lock != null && lock.isHeldByCurrentThread()) {
// 실제 락 해제
lock.unlock();
// 메모리 누수 방지(락이 비어있으면 제거)
/**
* 메모리 누수 방지 처리
*
* <p>hasQueuedThreads(): - 현재 이 락을 기다리는 스레드가 있는지 확인
*
* <p>대기 스레드가 없다면 locks 맵에서 제거하여 불필요한 Lock 객체 정리
*/
if (!lock.hasQueuedThreads()) {
/**
* remove(key, lock):
*
* <p>- 현재 맵에 등록된 값이 'lock'일 경우에만 제거 - 동시성 안전 (CAS 방식)
*/
locks.remove(key, lock);
}
}