瀏覽代碼

修改读写锁的操作地方,修改读取是否上锁的方法错误

luoshi 6 年之前
父節點
當前提交
d7670201df

+ 2 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/lock/LockService.java

@@ -9,7 +9,7 @@ import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.stereotype.Component;
 
-import cn.com.qmth.stmms.biz.lock.impl.MemoryLockProvider;
+import cn.com.qmth.stmms.biz.lock.impl.JdkLockProvider;
 import cn.com.qmth.stmms.common.enums.LockType;
 
 @Component("lockService")
@@ -100,7 +100,7 @@ public class LockService implements InitializingBean, ApplicationContextAware {
 
     @Override
     public void afterPropertiesSet() throws Exception {
-        this.provider = this.context.getBean(MemoryLockProvider.class);
+        this.provider = this.context.getBean(JdkLockProvider.class);
     }
 
     @Override

+ 4 - 4
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/lock/impl/MemoryLockProvider.java → stmms-biz/src/main/java/cn/com/qmth/stmms/biz/lock/impl/JdkLockProvider.java

@@ -18,8 +18,8 @@ import cn.com.qmth.stmms.common.enums.LockType;
  * @author luoshi
  *
  */
-@Component("memoryLockProvider")
-public class MemoryLockProvider implements LockProvider {
+@Component("jdkLockProvider")
+public class JdkLockProvider implements LockProvider {
 
     private Map<LockType, Map<String, ReentrantReadWriteLock>> lockMap = new HashMap<>();
 
@@ -35,7 +35,7 @@ public class MemoryLockProvider implements LockProvider {
 
     @Override
     public boolean isLocked(LockType type, String key) {
-        return getLock(type, key).writeLock().getHoldCount() > 0;
+        return getLock(type, key).isWriteLocked();
     }
 
     @Override
@@ -87,7 +87,7 @@ public class MemoryLockProvider implements LockProvider {
             for (Map<String, ReentrantReadWriteLock> map : lockMap.values()) {
                 Set<String> keys = new HashSet<>();
                 for (Entry<String, ReentrantReadWriteLock> entry : map.entrySet()) {
-                    if (!entry.getValue().isWriteLocked()) {
+                    if (!entry.getValue().isWriteLocked() && entry.getValue().getReadLockCount() == 0) {
                         keys.add(entry.getKey());
                     }
                 }

+ 12 - 14
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/thread/MarkQualityThread.java

@@ -1,15 +1,15 @@
 package cn.com.qmth.stmms.biz.mark.thread;
 
-import java.util.LinkedList;
 import java.util.List;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.biz.lock.LockService;
 import cn.com.qmth.stmms.biz.mark.service.MarkService;
 import cn.com.qmth.stmms.biz.utils.SpringContextHolder;
-import cn.com.qmth.stmms.common.utils.Callback;
+import cn.com.qmth.stmms.common.enums.LockType;
 
 /**
  * 评卷员计算评卷质量指标工作包装线程
@@ -23,23 +23,23 @@ public class MarkQualityThread implements Runnable {
 
     private List<Marker> markers;
 
-    private Callback callback;
+    private String lockKey;
 
-    public MarkQualityThread(Marker marker, Callback callback) {
-        this.markers = new LinkedList<>();
-        this.markers.add(marker);
-        this.callback = callback;
-    }
-
-    public MarkQualityThread(List<Marker> markers, Callback callback) {
+    public MarkQualityThread(List<Marker> markers, String lockKey) {
         this.markers = markers;
-        this.callback = callback;
+        this.lockKey = lockKey;
     }
 
     @Override
     public void run() {
+        LockService lockService = SpringContextHolder.getBean(LockService.class);
         MarkService markService = SpringContextHolder.getBean(MarkService.class);
 
+        if (!lockService.trylock(LockType.BATCH_QUALITY, lockKey)) {
+            log.info("mark quality thread lock faile for key=" + lockKey);
+            return;
+        }
+
         if (markers != null && markService != null) {
             for (Marker marker : markers) {
                 try {
@@ -49,8 +49,6 @@ public class MarkQualityThread implements Runnable {
                 }
             }
         }
-        if (callback != null) {
-            callback.invoke();
-        }
+        lockService.unlock(LockType.BATCH_QUALITY, lockKey);
     }
 }

+ 2 - 9
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkQualityController.java

@@ -33,7 +33,6 @@ import cn.com.qmth.stmms.biz.mark.thread.MarkQualityThread;
 import cn.com.qmth.stmms.common.domain.WebUser;
 import cn.com.qmth.stmms.common.enums.LibraryStatus;
 import cn.com.qmth.stmms.common.enums.LockType;
-import cn.com.qmth.stmms.common.utils.Callback;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
 
 @Controller("markQualityController")
@@ -96,15 +95,9 @@ public class MarkQualityController extends BaseExamController {
         MarkGroup group = groupService.findOne(examId, subjectCode, groupNumber);
         if (group != null) {
             final String lockKey = getLockKey(examId, subjectCode, groupNumber);
-            if (lockService.trylock(LockType.BATCH_QUALITY, lockKey)) {
+            if (!lockService.isLocked(LockType.BATCH_QUALITY, lockKey)) {
                 taskExecutor.submit(new MarkQualityThread(
-                        markerService.findByExamAndSubjectAndGroup(examId, subjectCode, groupNumber), new Callback() {
-
-                            @Override
-                            public void invoke() {
-                                lockService.unlock(LockType.BATCH_QUALITY, lockKey);
-                            }
-                        }));
+                        markerService.findByExamAndSubjectAndGroup(examId, subjectCode, groupNumber), lockKey));
             }
             redirectAttributes.addAttribute("groupNumber", groupNumber);
         }

+ 5 - 5
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ScoreController.java

@@ -196,7 +196,7 @@ public class ScoreController extends BaseExamController {
     @RoleRequire(Role.SCHOOL_ADMIN)
     public ModelAndView calculate(HttpServletRequest request) {
         int examId = getSessionExamId(request);
-        if (lockService.trylock(LockType.SCORE_CALCULATE, examId)) {
+        if (!lockService.isLocked(LockType.SCORE_CALCULATE, examId)) {
             ScoreCalculateThread thread = new ScoreCalculateThread(examId, lockService, studentService, questionService,
                     markService, reportService, examService, subjectService, groupService);
             taskExecutor.submit(thread);
@@ -276,7 +276,7 @@ public class ScoreController extends BaseExamController {
         }
         return obj;
     }
-    
+
     @RequestMapping("/getProcess")
     @ResponseBody
     public JSONObject getProcess(HttpServletRequest request) {
@@ -285,10 +285,10 @@ public class ScoreController extends BaseExamController {
         boolean running = lockService.isLocked(LockType.SCORE_CALCULATE, examId);
         JSONObject obj = new JSONObject();
         obj.accumulate("running", running);
-        if(exam.getProcess()!=null){
+        if (exam.getProcess() != null) {
             DecimalFormat format = new DecimalFormat("##.##");
-            obj.accumulate("process", format.format(exam.getProcess()*100));
-        }else{
+            obj.accumulate("process", format.format(exam.getProcess() * 100));
+        } else {
             obj.accumulate("process", 0);
         }
         return obj;

+ 6 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/thread/ScoreCalculateThread.java

@@ -78,6 +78,12 @@ public class ScoreCalculateThread implements Runnable {
 
     @Override
     public void run() {
+        // 尝试上锁
+        if (!lockService.trylock(LockType.SCORE_CALCULATE, examId)) {
+            log.info("calculate lock faile for examId=" + examId);
+            return;
+        }
+        // 上锁成功正式开始
         log.info("start calculate for examId=" + examId);
         try {
             // 获取考试信息

+ 1 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/PictureController.java

@@ -114,7 +114,7 @@ public class PictureController {
             result.accumulate("message", "file.save not exists");
             return result;
         }
-        if (lockService.trylock(LockType.SAVE_SHEET, examId)) {
+        if (!lockService.isLocked(LockType.SAVE_SHEET, examId)) {
             taskExecutor.submit(new SheetDownloadThread(examId, saveDir, withTag, this, studentService, lockService));
         }
         result.accumulate("running", lockService.isLocked(LockType.SAVE_SHEET, examId));

+ 25 - 18
stmms-web/src/main/java/cn/com/qmth/stmms/api/utils/SheetDownloadThread.java

@@ -43,28 +43,35 @@ public class SheetDownloadThread implements Runnable {
 
     @Override
     public void run() {
-        ExamStudentSearchQuery query = new ExamStudentSearchQuery();
-        query.setExamId(examId);
-        query.setUpload(true);
-        query.setPageSize(100);
-        query.setPageNumber(0);
-
-        while (true) {
-            query.setPageNumber(query.getPageNumber() + 1);
-            query = studentService.findByQuery(query);
-            if (query.getCurrentCount() == 0) {
-                break;
-            }
+        if (!lockService.trylock(LockType.SAVE_SHEET, examId)) {
+            return;
+        }
 
-            for (ExamStudent student : query.getResult()) {
-                log.info("write for student: " + student.getExamNumber());
-                for (int i = 1; i <= student.getSheetCount(); i++) {
-                    download(student, i);
+        try {
+            ExamStudentSearchQuery query = new ExamStudentSearchQuery();
+            query.setExamId(examId);
+            query.setUpload(true);
+            query.setPageSize(100);
+            query.setPageNumber(0);
+            while (true) {
+                query.setPageNumber(query.getPageNumber() + 1);
+                query = studentService.findByQuery(query);
+                if (query.getCurrentCount() == 0) {
+                    break;
+                }
+
+                for (ExamStudent student : query.getResult()) {
+                    log.info("write for student: " + student.getExamNumber());
+                    for (int i = 1; i <= student.getSheetCount(); i++) {
+                        download(student, i);
+                    }
                 }
             }
+        } catch (Exception e) {
+            log.error("save sheet thread error", e);
+        } finally {
+            lockService.unlock(LockType.SAVE_SHEET, examId);
         }
-
-        lockService.unlock(LockType.SAVE_SHEET, examId);
     }
 
     private void download(ExamStudent student, int index) {