|
@@ -1,7 +1,11 @@
|
|
|
package cn.com.qmth.stmms.biz.mark.service.Impl;
|
|
|
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
import java.util.Map;
|
|
|
-import java.util.concurrent.ConcurrentHashMap;
|
|
|
+import java.util.Map.Entry;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
@@ -19,9 +23,9 @@ public class MarkLockService {
|
|
|
|
|
|
protected static final Logger log = LoggerFactory.getLogger(MarkLockService.class);
|
|
|
|
|
|
- private Map<String, Boolean> groupMap = new ConcurrentHashMap<>();
|
|
|
+ private Map<Object, AtomicBoolean> groupMap = new HashMap<>();
|
|
|
|
|
|
- private Map<Integer, Boolean> studentMap = new ConcurrentHashMap<>();
|
|
|
+ private Map<Object, AtomicBoolean> studentMap = new HashMap<>();
|
|
|
|
|
|
/**
|
|
|
* 对评卷分组进行重置/删除操作前,先尝试锁定
|
|
@@ -29,7 +33,10 @@ public class MarkLockService {
|
|
|
* @param group
|
|
|
*/
|
|
|
public void lockGroup(Integer examId, String subjectCode, Integer groupNumber) {
|
|
|
- groupMap.put(getKey(examId, subjectCode, groupNumber), Boolean.TRUE);
|
|
|
+ AtomicBoolean lock = getLock(groupMap, getKey(examId, subjectCode, groupNumber));
|
|
|
+ while (!lock.get()) {
|
|
|
+ lock.compareAndSet(false, true);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -38,7 +45,10 @@ public class MarkLockService {
|
|
|
* @param group
|
|
|
*/
|
|
|
public void unlockGroup(Integer examId, String subjectCode, Integer groupNumber) {
|
|
|
- groupMap.remove(getKey(examId, subjectCode, groupNumber));
|
|
|
+ AtomicBoolean lock = getLock(groupMap, getKey(examId, subjectCode, groupNumber));
|
|
|
+ while (lock != null && lock.get()) {
|
|
|
+ lock.compareAndSet(true, false);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -47,8 +57,8 @@ public class MarkLockService {
|
|
|
* @param group
|
|
|
*/
|
|
|
public void waitUnlockGroup(Integer examId, String subjectCode, Integer groupNumber) {
|
|
|
- String key = getKey(examId, subjectCode, groupNumber);
|
|
|
- while (groupMap.get(key) != null) {
|
|
|
+ AtomicBoolean lock = getLock(groupMap, getKey(examId, subjectCode, groupNumber));
|
|
|
+ while (lock.get()) {
|
|
|
;
|
|
|
}
|
|
|
}
|
|
@@ -59,7 +69,10 @@ public class MarkLockService {
|
|
|
* @param studentId
|
|
|
*/
|
|
|
public void lockStudent(Integer studentId) {
|
|
|
- studentMap.put(studentId, Boolean.TRUE);
|
|
|
+ AtomicBoolean lock = getLock(studentMap, studentId);
|
|
|
+ while (!lock.get()) {
|
|
|
+ lock.compareAndSet(false, true);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -68,7 +81,10 @@ public class MarkLockService {
|
|
|
* @param studentId
|
|
|
*/
|
|
|
public void unlockStudent(Integer studentId) {
|
|
|
- studentMap.remove(studentId);
|
|
|
+ AtomicBoolean lock = getLock(studentMap, studentId);
|
|
|
+ while (lock.get()) {
|
|
|
+ lock.compareAndSet(true, false);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -77,11 +93,49 @@ public class MarkLockService {
|
|
|
* @param studentId
|
|
|
*/
|
|
|
public void waitUnlockStudent(Integer studentId) {
|
|
|
- while (studentMap.get(studentId) != null) {
|
|
|
+ AtomicBoolean lock = getLock(studentMap, studentId);
|
|
|
+ while (lock.get()) {
|
|
|
;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public void clear() {
|
|
|
+ clearLock(groupMap);
|
|
|
+ clearLock(studentMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void clearLock(Map<Object, AtomicBoolean> map) {
|
|
|
+ if (map.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ synchronized (map) {
|
|
|
+ Set<Object> keys = new HashSet<>();
|
|
|
+ for (Entry<Object, AtomicBoolean> entry : map.entrySet()) {
|
|
|
+ if (!entry.getValue().get()) {
|
|
|
+ keys.add(entry.getKey());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (Object key : keys) {
|
|
|
+ map.remove(key);
|
|
|
+ }
|
|
|
+ keys.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private AtomicBoolean getLock(Map<Object, AtomicBoolean> map, Object key) {
|
|
|
+ AtomicBoolean lock = map.get(key);
|
|
|
+ if (lock == null) {
|
|
|
+ synchronized (map) {
|
|
|
+ lock = map.get(key);
|
|
|
+ if (lock == null) {
|
|
|
+ lock = new AtomicBoolean(false);
|
|
|
+ map.put(key, lock);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return lock;
|
|
|
+ }
|
|
|
+
|
|
|
private String getKey(Integer examId, String subjectCode, Integer groupNumber) {
|
|
|
return examId + "_" + subjectCode + "_" + groupNumber;
|
|
|
}
|