|
@@ -1,5 +1,6 @@
|
|
package com.qmth.distributed.print.api.obe;
|
|
package com.qmth.distributed.print.api.obe;
|
|
|
|
|
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
@@ -46,6 +47,7 @@ import com.qmth.teachcloud.obe.service.*;
|
|
import io.swagger.annotations.*;
|
|
import io.swagger.annotations.*;
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
import org.apache.commons.io.FileUtils;
|
|
import org.apache.commons.io.FileUtils;
|
|
|
|
+import org.apache.commons.io.IOUtils;
|
|
import org.apache.poi.ss.usermodel.*;
|
|
import org.apache.poi.ss.usermodel.*;
|
|
import org.apache.poi.ss.util.CellRangeAddress;
|
|
import org.apache.poi.ss.util.CellRangeAddress;
|
|
import org.apache.poi.ss.util.RegionUtil;
|
|
import org.apache.poi.ss.util.RegionUtil;
|
|
@@ -62,11 +64,15 @@ import javax.annotation.Resource;
|
|
import javax.validation.Valid;
|
|
import javax.validation.Valid;
|
|
import javax.validation.constraints.Max;
|
|
import javax.validation.constraints.Max;
|
|
import javax.validation.constraints.Min;
|
|
import javax.validation.constraints.Min;
|
|
-import java.io.File;
|
|
|
|
-import java.io.FileInputStream;
|
|
|
|
-import java.io.InputStream;
|
|
|
|
|
|
+import java.io.*;
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
|
|
+import java.nio.charset.Charset;
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
+import java.text.MessageFormat;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
+import java.util.concurrent.CopyOnWriteArrayList;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@@ -711,7 +717,7 @@ public class TRBasicInfoController {
|
|
public Result wordTopdfTest() throws Exception {
|
|
public Result wordTopdfTest() throws Exception {
|
|
if (customRedisLockProvider.tryLock(LockType.CREATE_PDF, "1")) {
|
|
if (customRedisLockProvider.tryLock(LockType.CREATE_PDF, "1")) {
|
|
try {
|
|
try {
|
|
- if (!customRedisLockProvider.isLocked(LockType.CREATE_PDF, "1")) {
|
|
|
|
|
|
+ if (!customRedisLockProvider.isWriteLocked(LockType.CREATE_PDF, "1")) {
|
|
customRedisLockProvider.waitLock(LockType.CREATE_PDF, "1");
|
|
customRedisLockProvider.waitLock(LockType.CREATE_PDF, "1");
|
|
}
|
|
}
|
|
customRedisLockProvider.watch(LockType.CREATE_PDF, "1");
|
|
customRedisLockProvider.watch(LockType.CREATE_PDF, "1");
|
|
@@ -728,4 +734,170 @@ public class TRBasicInfoController {
|
|
}
|
|
}
|
|
return ResultUtil.ok(true);
|
|
return ResultUtil.ok(true);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ public static boolean threadBreak = false;
|
|
|
|
+ public static CopyOnWriteArrayList<Integer> threadKeyList = new CopyOnWriteArrayList<>();
|
|
|
|
+ public static String path = "/Users/king/Downloads/";
|
|
|
|
+ public static File fileDir = new File(path + "thread_test");
|
|
|
|
+ public static final String lockName = ":txt:file";
|
|
|
|
+ public static final String one = "[一]";
|
|
|
|
+ public static final String two = "[二]";
|
|
|
|
+ public static ConcurrentHashMap<Integer, Integer> keyMap = new ConcurrentHashMap<>();
|
|
|
|
+
|
|
|
|
+ @ApiOperation(value = "线程测试")
|
|
|
|
+ @RequestMapping(value = "/thread/test", method = RequestMethod.POST)
|
|
|
|
+ @ApiResponses({@ApiResponse(code = 200, message = "测试成功", response = Object.class)})
|
|
|
|
+ @Aac(auth = false)
|
|
|
|
+ public Result threadTest() throws IOException, Exception {
|
|
|
|
+ threadBreak = false;
|
|
|
|
+ AtomicInteger threadReleaseToatlCount = new AtomicInteger(0);
|
|
|
|
+ threadKeyList.clear();
|
|
|
|
+ keyMap.clear();
|
|
|
|
+ int num = 100;
|
|
|
|
+ for (; ; ) {
|
|
|
|
+ int key = new Random().nextInt(num) + 1;
|
|
|
|
+ if (!keyMap.containsKey(key)) {
|
|
|
|
+ keyMap.put(key, key);
|
|
|
|
+ new Thread(() -> {
|
|
|
|
+ //开始尝试获取锁
|
|
|
|
+ if (customRedisLockProvider.tryLock(LockType.CREATE_PDF, key + "", 1L, TimeUnit.DAYS)) {
|
|
|
|
+ log.info("########线程key:{}已获得锁########", key);
|
|
|
|
+ try {
|
|
|
|
+ StringJoiner stringJoinerSummary = this.readTxtFile(key + "");
|
|
|
|
+ this.writeTxtFile(stringJoinerSummary, key + "", one + "->线程key:" + key + "已获得锁");
|
|
|
|
+ } catch (IOException | InterruptedException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ threadKeyList.add(key);
|
|
|
|
+ long i = 0;
|
|
|
|
+ do {
|
|
|
|
+ i = i + new Random().nextInt(100) + 1;
|
|
|
|
+ if ((Thread.currentThread().getId() & 1) == 0) {
|
|
|
|
+ Thread.sleep(new Random().nextInt(100) + 1);
|
|
|
|
+ } else {
|
|
|
|
+ Thread.sleep(new Random().nextInt(50) + 1);
|
|
|
|
+ }
|
|
|
|
+ } while (i < 100000);
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ } finally {
|
|
|
|
+ customRedisLockProvider.unlock(LockType.CREATE_PDF, key + "");
|
|
|
|
+ threadReleaseToatlCount.incrementAndGet();
|
|
|
|
+ log.info("########线程key:{}已被释放,总计:{}########", key, threadReleaseToatlCount.get());
|
|
|
|
+ try {
|
|
|
|
+ StringJoiner stringJoinerSummary = this.readTxtFile(key + "");
|
|
|
|
+ this.writeTxtFile(stringJoinerSummary, key + "", one + "->线程key:" + key + "已被释放");
|
|
|
|
+ } catch (InterruptedException | IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ if (threadReleaseToatlCount.get() == num) {
|
|
|
|
+ threadBreak = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }).start();
|
|
|
|
+ }
|
|
|
|
+ Thread.sleep(1000);
|
|
|
|
+ if (keyMap.size() == num) {
|
|
|
|
+ log.info("########线程生成完毕########");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return ResultUtil.ok(true);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @ApiOperation(value = "线程抢夺测试")
|
|
|
|
+ @RequestMapping(value = "/thread/reave/test", method = RequestMethod.POST)
|
|
|
|
+ @ApiResponses({@ApiResponse(code = 200, message = "测试成功", response = Object.class)})
|
|
|
|
+ @Aac(auth = false)
|
|
|
|
+ public Result threadReaveTest() throws IOException, Exception {
|
|
|
|
+ AtomicInteger threadReaveToatlCount = new AtomicInteger(0);
|
|
|
|
+ //开始尝试获取锁
|
|
|
|
+ for (; ; ) {
|
|
|
|
+ int index = new Random().nextInt(threadKeyList.size());
|
|
|
|
+ int key = threadKeyList.get(index);
|
|
|
|
+ if (customRedisLockProvider.tryLock(LockType.CREATE_PDF, key + "")) {
|
|
|
|
+ log.info("%%%%%%%%%线程key:{}抢到锁%%%%%%%%%", key);
|
|
|
|
+ StringJoiner stringJoinerSummary = this.readTxtFile(key + "");
|
|
|
|
+ this.writeTxtFile(stringJoinerSummary, key + "", two + "->线程key:" + key + "抢到锁");
|
|
|
|
+ threadReaveToatlCount.incrementAndGet();
|
|
|
|
+ threadKeyList.remove(key);
|
|
|
|
+ customRedisLockProvider.unlock(LockType.CREATE_PDF, key + "");
|
|
|
|
+ } else {
|
|
|
|
+ log.info("%%%%%%%%%线程key:{}正被锁定%%%%%%%%%", key);
|
|
|
|
+ StringJoiner stringJoinerSummary = this.readTxtFile(key + "");
|
|
|
|
+ this.writeTxtFile(stringJoinerSummary, key + "", two + "->线程key:" + key + "正被锁定");
|
|
|
|
+ }
|
|
|
|
+ Thread.sleep(1000);
|
|
|
|
+ if (threadKeyList.size() == 0 || threadBreak) {
|
|
|
|
+ log.info("%%%%%%%%%线程抢夺完毕%%%%%%%%%,总计:{}", threadReaveToatlCount.get());
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return ResultUtil.ok(true);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取txt文件读锁
|
|
|
|
+ *
|
|
|
|
+ * @param key
|
|
|
|
+ * @return
|
|
|
|
+ * @throws IOException
|
|
|
|
+ */
|
|
|
|
+ protected StringJoiner readTxtFile(String key) throws IOException {
|
|
|
|
+ if (!fileDir.exists()) {
|
|
|
|
+ fileDir.mkdirs();
|
|
|
|
+ }
|
|
|
|
+ File file = new File(fileDir.getPath() + File.separator + key + ".txt");
|
|
|
|
+ if (!file.exists()) {
|
|
|
|
+ file.createNewFile();
|
|
|
|
+ }
|
|
|
|
+ StringJoiner stringJoinerSummary = new StringJoiner("\n");
|
|
|
|
+ try {
|
|
|
|
+ customRedisLockProvider.watch(LockType.CREATE_PDF, key + lockName + ":read");
|
|
|
|
+ String text = IOUtils.toString(new FileInputStream(file), Charset.forName(SystemConstant.CHARSET_NAME));
|
|
|
|
+ if (Objects.nonNull(text) && !Objects.equals(text.trim(), "")) {
|
|
|
|
+ stringJoinerSummary.add(text);
|
|
|
|
+ }
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ } finally {
|
|
|
|
+ customRedisLockProvider.unwatch(LockType.CREATE_PDF, key + lockName + ":read");
|
|
|
|
+ }
|
|
|
|
+ return stringJoinerSummary;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * txt文件写锁
|
|
|
|
+ *
|
|
|
|
+ * @param stringJoinerSummary
|
|
|
|
+ * @param key
|
|
|
|
+ * @param message
|
|
|
|
+ * @throws InterruptedException
|
|
|
|
+ */
|
|
|
|
+ protected void writeTxtFile(StringJoiner stringJoinerSummary, String key, String message) throws InterruptedException, IOException {
|
|
|
|
+ if (!fileDir.exists()) {
|
|
|
|
+ fileDir.mkdirs();
|
|
|
|
+ }
|
|
|
|
+ File file = new File(fileDir.getPath() + File.separator + key + ".txt");
|
|
|
|
+ if (!file.exists()) {
|
|
|
|
+ file.createNewFile();
|
|
|
|
+ }
|
|
|
|
+ for (; ; ) {
|
|
|
|
+ if (!customRedisLockProvider.isWriteLocked(LockType.CREATE_PDF, key + lockName + ":wirte")) {
|
|
|
|
+ try {
|
|
|
|
+ customRedisLockProvider.waitLock(LockType.CREATE_PDF, key + lockName + ":wirte");
|
|
|
|
+ stringJoinerSummary.add(MessageFormat.format("{0}{1}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), message));
|
|
|
|
+ IOUtils.write(stringJoinerSummary.toString().getBytes(StandardCharsets.UTF_8), new FileOutputStream(file));
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ } finally {
|
|
|
|
+ customRedisLockProvider.unlock(LockType.CREATE_PDF, key + lockName + ":wirte");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Thread.sleep(500);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|