当前位置: 首页> 房产> 建材 > Java 处理一张单据,处理花费时间挺久,有单号,不用redis怎么可以快速判断其在处理中,不需要再处理

Java 处理一张单据,处理花费时间挺久,有单号,不用redis怎么可以快速判断其在处理中,不需要再处理

时间:2025/8/2 13:21:53来源:https://blog.csdn.net/chengmin123456789/article/details/140951322 浏览次数:0次

在Java中处理长时间的任务并且需要避免重复处理同一张单据的情况下,在不使用Redis或其他外部存储服务情况下。

方法一:使用数据库表 表记录记录状态

方法二:使用文件系统 创建和删除文件记录状态

方法三:使用本地缓存

import java.util.concurrent.ConcurrentHashMap;public class OrderStatusService {private final ConcurrentHashMap<String, Boolean> processingOrders = new ConcurrentHashMap<>();public boolean isOrderBeingProcessed(String orderNumber) {return processingOrders.getOrDefault(orderNumber, false);}public void markOrderAsProcessing(String orderNumber) {processingOrders.put(orderNumber, true);}public void markOrderAsCompleted(String orderNumber) {processingOrders.remove(orderNumber);}
}

@Sl4j
public class OrderProcessor {private final OrderStatusService orderStatusService;public OrderProcessor(OrderStatusService orderStatusService) {this.orderStatusService = orderStatusService;}public void processOrder(String orderNumber) {log.info("Order " + orderNumber + " startProcess.");if (!orderStatusService.isOrderBeingProcessed(orderNumber)) {try {orderStatusService.markOrderAsProcessing(orderNumber);// 处理单据的业务逻辑handleBusinessLogic(orderNumber);orderStatusService.markOrderAsCompleted(orderNumber);} catch (Exception e) {// 处理异常情况e.printStackTrace();}}else{log.error("Order " + orderNumber + " repeat.");}}private void handleBusinessLogic(String orderNumber) {// 模拟处理逻辑try {Thread.sleep(60000); // 模拟长时间处理} catch (InterruptedException e) {e.printStackTrace();}log.info("Order " + orderNumber + " processed.");}}

模拟测试:

public static void main(String[] args) throws Exception{OrderStatusService orderStatusService=new OrderStatusService();OrderProcessor orderProcessor=new OrderProcessor(orderStatusService);
//        orderProcessor.processOrder("1111");
//        orderProcessor.processOrder("2222");
//        orderProcessor.processOrder("1111");ExecutorService executor = Executors.newFixedThreadPool(5); // 创建一个固定大小的线程池executor.submit(new TaskRunner(1,"1111",orderProcessor));Thread.sleep(200);executor.submit(new TaskRunner(2,"2222",orderProcessor));Thread.sleep(200);executor.submit(new TaskRunner(3,"1111",orderProcessor));executor.shutdown(); // 关闭线程池}static class TaskRunner implements Runnable {private final int taskId;private final String orderNumber;private final OrderProcessor orderProcessor;public TaskRunner(int taskId,String orderNumber,OrderProcessor orderProcessor) {this.taskId = taskId;this.orderNumber = orderNumber;this.orderProcessor = orderProcessor;}@Overridepublic void run() {log.info("Task " + taskId + " is running on " + Thread.currentThread().getName());orderProcessor.processOrder(orderNumber);log.info("Task " + taskId + " completed.");}}

运行结果:

   

注意事项

如果使用数据库,需要考虑并发控制和事务管理。

如果使用文件锁,需要考虑文件系统的可靠性和性能。

如果使用本地缓存,需要考虑缓存的过期时间和集群环境下的同步问题。

关键字:Java 处理一张单据,处理花费时间挺久,有单号,不用redis怎么可以快速判断其在处理中,不需要再处理

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: