haogh 1 månad sedan
förälder
incheckning
d844f386d0

+ 36 - 8
src/main/java/com/qmth/pdf/tools/service/impl/StudentPaperServiceImpl.java

@@ -63,6 +63,9 @@ public class StudentPaperServiceImpl implements StudentPaperService {
     private static final TypeReference<List<StudentAnswerBean>> STUDENT_ANSWER_LIST_TYPE_REFERENCE =
             new TypeReference<List<StudentAnswerBean>>() {};
 
+    private final ThreadLocal<PaperBean> threadLocalPaper = new ThreadLocal<>();
+
+
     @Autowired
     public StudentPaperServiceImpl(RestTemplate restTemplate, PdfConfig pdfConfig, ThreadPoolTaskExecutor taskExecutor) {
         this.httpClient = new HttpClientUtil(restTemplate);
@@ -141,16 +144,16 @@ public class StudentPaperServiceImpl implements StudentPaperService {
 
     private void processStudent(StudentBean studentBean, Long examId) {
         String subjectCode = studentBean.getSubjectCode();
-        PaperBean paperBean;
+        PaperBean cachedPaperBean;
 
-        // 从缓存中获取试卷结构
-        if ((paperBean = paperCache.getIfPresent(subjectCode)) == null) {
+        // 从缓存中获取原始试卷模板
+        if ((cachedPaperBean = paperCache.getIfPresent(subjectCode)) == null) {
             synchronized (this) {
-                if ((paperBean = paperCache.getIfPresent(subjectCode)) == null) {
+                if ((cachedPaperBean = paperCache.getIfPresent(subjectCode)) == null) {
                     try {
-                        paperBean = fetchPaperStructure(examId, subjectCode);
-                        if (paperBean != null) {
-                            paperCache.put(subjectCode, paperBean);
+                        cachedPaperBean = fetchPaperStructure(examId, subjectCode);
+                        if (cachedPaperBean != null) {
+                            paperCache.put(subjectCode, cachedPaperBean);
                         }
                     } catch (Exception e) {
                         log.error("从远程获取试卷结构失败, examId:{}, subjectCode:{}", examId, subjectCode, e);
@@ -159,11 +162,28 @@ public class StudentPaperServiceImpl implements StudentPaperService {
             }
         }
 
-        if (paperBean == null) {
+        if (cachedPaperBean == null) {
             log.warn("找不到该科目对应的试卷, examId:{}, subjectCode:{}", examId, subjectCode);
             return;
         }
 
+        // 从 ThreadLocal 获取当前线程的 paperBean 副本
+        PaperBean paperBean = threadLocalPaper.get();
+        if (paperBean == null) {
+            try {
+                // 深拷贝原始试卷结构到当前线程私有对象
+                paperBean = deepCopy(cachedPaperBean);
+                threadLocalPaper.set(paperBean);
+            } catch (IOException e) {
+                log.error("深拷贝试卷结构失败", e);
+                return;
+            }
+        }
+
+        // 填充考生信息(不会影响其他线程)
+        paperBean.setStudentName(studentBean.getName());
+        paperBean.setStudentCode(studentBean.getStudentCode());
+
         //试卷的大题集合
         List<DetailBean> details = paperBean.getDetails();
         if (CollectionUtils.isEmpty(details)) {
@@ -189,8 +209,16 @@ public class StudentPaperServiceImpl implements StudentPaperService {
 
         // 将填充后的试卷写到文件中
         outputToFile(studentBean, paperBean, examId);
+
+        // 清理 ThreadLocal 避免内存泄漏
+        threadLocalPaper.remove();
+    }
+
+    private PaperBean deepCopy(PaperBean original) throws IOException {
+        return objectMapper.readValue(objectMapper.writeValueAsBytes(original), PaperBean.class);
     }
 
+
     private void outputToFile(StudentBean studentBean, PaperBean paperBean, Long examId) {
         try {
             String json = objectMapper.writeValueAsString(paperBean);