|
@@ -1,8 +1,10 @@
|
|
|
package com.qmth.boot.core.concurrent.service.impl;
|
|
|
|
|
|
+import com.qmth.boot.core.concurrent.model.Semaphore;
|
|
|
import com.qmth.boot.core.concurrent.service.ConcurrentService;
|
|
|
|
|
|
import javax.annotation.PreDestroy;
|
|
|
+import javax.validation.constraints.NotNull;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
|
import java.util.concurrent.locks.Lock;
|
|
@@ -16,15 +18,19 @@ public class MemoryConcurrentService implements ConcurrentService {
|
|
|
|
|
|
private final Map<String, ReentrantReadWriteLock> readWriteMap;
|
|
|
|
|
|
+ private final Map<String, Semaphore> semaphoreMap;
|
|
|
+
|
|
|
public MemoryConcurrentService() {
|
|
|
this.lockMap = new HashMap<>();
|
|
|
this.readWriteMap = new HashMap<>();
|
|
|
+ this.semaphoreMap = new HashMap<>();
|
|
|
}
|
|
|
|
|
|
@PreDestroy
|
|
|
public void close() {
|
|
|
this.lockMap.clear();
|
|
|
this.readWriteMap.clear();
|
|
|
+ this.semaphoreMap.clear();
|
|
|
}
|
|
|
|
|
|
private ReentrantLock lock(String name) {
|
|
@@ -71,4 +77,34 @@ public class MemoryConcurrentService implements ConcurrentService {
|
|
|
public boolean isWriteLocked(String name) {
|
|
|
return readWriteLock(name).isWriteLocked();
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Semaphore getSemaphore(@NotNull String name) {
|
|
|
+ Semaphore semaphore = semaphoreMap.get(name);
|
|
|
+ if (semaphore == null) {
|
|
|
+ synchronized (semaphoreMap) {
|
|
|
+ semaphore = semaphoreMap.computeIfAbsent(name, key -> {
|
|
|
+ java.util.concurrent.Semaphore se = new java.util.concurrent.Semaphore(1, true);
|
|
|
+ return new Semaphore() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void acquire() throws InterruptedException {
|
|
|
+ se.acquire();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean tryAcquire() {
|
|
|
+ return se.tryAcquire();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void release() {
|
|
|
+ se.release();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return semaphore;
|
|
|
+ }
|
|
|
}
|