Hazelcast 5.5 버전부터 Lock 객체가 유료버전에서만 사용 가능하다.1 아래 코드는 Map2에 lock을 걸었다.
람다 메소드를 사용하여 공통모듈로 만듬. Spring AOP가 편리한데 public 메소드에만 적용가능하기 때문에 제외
import com.hazelcast.core.HazelcastInstance;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.function.Supplier;
@Component
@RequiredArgsConstructor
@Slf4j
public class DistributedLockExecutor {
private final HazelcastInstance hazelcastInstance;
public <T> T execute(String lockName, String logStr, Supplier<T> supplier) {
return executeWithLock(lockName, logStr, supplier);
}
public void execute(String lockName, String logStr, Runnable runnable) {
executeWithLock(lockName, logStr, () -> {
runnable.run();
return null;
});
}
private <T> T executeWithLock(String lockName, String logStr, Supplier<T> supplier) {
var lockMap = hazelcastInstance.getMap(lockName);
try {
lockMap.lock(lockName);
log.info("Acquired lock: [{}][{}]", lockName, logStr);
return supplier.get();
} catch (Exception e) {
log.error("Error executing task with lock: {}", lockName, e);
throw e;
} finally {
lockMap.unlock(lockName);
log.info("Released lock: [{}][{}]", lockName, logStr);
}
}
}
spring:
hazelcast:
config: classpath:hazelcast.yaml
hazelcast:
instance-name: hazelcast-instance
network:
port:
port: 5701
join:
multicast:
enabled: false
tcp-ip:
enabled: true
member-list:
- 127.0.0.1:5701
@SpringBootTest
class DistributedLockExecutorTest {
@Autowired
private HazelcastInstance hazelcastInstance;
@Autowired
private DistributedLockExecutor distributedLockExecutor;
@Test
void testLock() throws Exception {
Thread thread1 = new Thread(() -> {
String logStr = "lockTest#1";
distributedLockExecutor.execute("testLock", logStr,
() -> testRun(logStr));
});
thread1.start();
Thread thread2 = new Thread(() -> {
String logStr = "lockTest#2";
distributedLockExecutor.execute("testLock", logStr,
() -> testRun(logStr));
});
thread2.start();
thread1.join();
thread2.join();
}
@Test
void justTest() throws Exception {
Thread thread1 = new Thread(() -> {
testRun("justTest#1");
});
thread1.start();
Thread thread2 = new Thread(() -> {
testRun("justTest#2");
});
thread2.start();
thread1.join();
thread2.join();
}
void testRun(String myName) {
try {
for (int i = 0; i < 10; i++) {
System.out.println("Hello, " + myName + "! This is message number " + (i + 1));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("Thread was interrupted: " + e.getMessage());
}
}
}
Hello, justTest#1! This is message number 1
Hello, justTest#2! This is message number 1
Hello, justTest#2! This is message number 2
Hello, justTest#1! This is message number 2
Hello, justTest#2! This is message number 3
Hello, justTest#1! This is message number 3
Hello, justTest#2! This is message number 4
Hello, justTest#1! This is message number 4
Hello, justTest#2! This is message number 5
Hello, justTest#1! This is message number 5
Hello, justTest#2! This is message number 6
Hello, justTest#1! This is message number 6
Hello, justTest#2! This is message number 7
Hello, justTest#1! This is message number 7
Hello, justTest#2! This is message number 8
Hello, justTest#1! This is message number 8
Hello, justTest#2! This is message number 9
Hello, justTest#1! This is message number 9
Hello, justTest#2! This is message number 10
Hello, justTest#1! This is message number 10
2025-07-01T21:28:09.440+09:00 INFO 16224 --- [ Thread-7] org.example.DistributedLockExecutor : Acquired lock: [testLock][lockTest#2]
Hello, lockTest#2! This is message number 1
Hello, lockTest#2! This is message number 2
Hello, lockTest#2! This is message number 3
Hello, lockTest#2! This is message number 4
Hello, lockTest#2! This is message number 5
Hello, lockTest#2! This is message number 6
Hello, lockTest#2! This is message number 7
Hello, lockTest#2! This is message number 8
Hello, lockTest#2! This is message number 9
Hello, lockTest#2! This is message number 10
2025-07-01T21:28:19.551+09:00 INFO 16224 --- [ Thread-7] org.example.DistributedLockExecutor : Released lock: [testLock][lockTest#2]
2025-07-01T21:28:19.552+09:00 INFO 16224 --- [ Thread-6] org.example.DistributedLockExecutor : Acquired lock: [testLock][lockTest#1]
Hello, lockTest#1! This is message number 1
Hello, lockTest#1! This is message number 2
Hello, lockTest#1! This is message number 3
Hello, lockTest#1! This is message number 4
Hello, lockTest#1! This is message number 5
Hello, lockTest#1! This is message number 6
Hello, lockTest#1! This is message number 7
Hello, lockTest#1! This is message number 8
Hello, lockTest#1! This is message number 9
Hello, lockTest#1! This is message number 10
2025-07-01T21:28:29.643+09:00 INFO 16224 --- [ Thread-6] org.example.DistributedLockExecutor : Released lock: [testLock][lockTest#1]