From d22349714c8d199c02f336f90fba841ef8f5cd39 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期五, 21 十一月 2025 17:46:23 +0800
Subject: [PATCH] 优化内存后最终版202511211746

---
 src/publicway/ProtocolParser01.java |  371 +++++++++++++++++++++++-----------------------------
 1 files changed, 167 insertions(+), 204 deletions(-)

diff --git a/src/publicway/ProtocolParser01.java b/src/publicway/ProtocolParser01.java
index 4f0943c..2a2d4f0 100644
--- a/src/publicway/ProtocolParser01.java
+++ b/src/publicway/ProtocolParser01.java
@@ -1,13 +1,20 @@
 package publicway;
 import java.util.ArrayList;
 import java.util.List;
-
-import chuankou.SerialPortService;
 import chushihua.SlotManager;
 public class ProtocolParser01 {
+    
+    // 缓存常用字符串减少重复创建
+    private static final String[] WORK_STATUS_DESC = {"无效", "待机", "充电", "充满", "故障", "授权到期", "通信超时", "未知状态"};
+    private static final String[] DOOR_STATUS_DESC = {"未知状态", "开门状态", "关门状态"};
+    private static final String[] CARD_STATUS_DESC = {"无卡", "有卡", "读卡错误(卡非法)", "未知状态"};
+    
+    // StringBuilder 对象池
+    private static final ThreadLocal<StringBuilder> stringBuilderPool = 
+        ThreadLocal.withInitial(() -> new StringBuilder(512));
 
     /**
-     * 新增:直接使用字节数组解析的方法(避免字符串转换)
+     * 优化后的字节数组解析方法
      */
     public static ParseResult parseDDCC01Data(byte[] packetData) {
         if (packetData == null || packetData.length < 18) {
@@ -19,45 +26,49 @@
             throw new IllegalArgumentException("非DDCC协议数据");
         }
 
+        ParseResult result = ParseResultPool.borrowObject();
         try {
-            // 跳过包头DDCC (2字节),直接使用剩余数据
-            byte[] dataBytes = new byte[packetData.length - 2];
-            System.arraycopy(packetData, 2, dataBytes, 0, dataBytes.length);
-
-            if (dataBytes.length < 16) {
+            // 直接使用原数组,避免创建新数组
+            if (packetData.length < 18) { // 2(包头) + 16(最小数据长度)
                 throw new IllegalArgumentException("数据长度不足");
             }
 
-            // 2. 解析各个字段
-            int dataLength = parseDataLength(dataBytes);
-            int hostAddress = parseHostAddress(dataBytes);
-            int slotNumber = parseSlotNumber(dataBytes);
-            int functionCode = parseFunctionCode(dataBytes);
-            WorkStatus workStatus = parseWorkStatus(dataBytes);
-            DoorStatus doorStatus = parseDoorStatus(dataBytes);
-            CardStatus cardStatus = parseCardStatus(dataBytes);
-            int cardStatusChange = parseCardStatusChange(dataBytes);
-            String cardNumber = parseCardNumber(dataBytes);
-            List<FaultType> faults = parseFaults(dataBytes);
-            double voltage = parseVoltage(dataBytes);
-            double current = parseCurrent(dataBytes);
+            // 解析各个字段
+            int dataLength = parseDataLength(packetData, 2);
+            int hostAddress = parseHostAddress(packetData, 4);
+            int slotNumber = parseSlotNumber(packetData, 5);
+            int functionCode = parseFunctionCode(packetData, 6);
 
-            // 3. 验证功能码
+            // 验证功能码
             if (functionCode != 0x01) {
                 throw new IllegalArgumentException("非01功能码数据");
             }
 
-            return new ParseResult(hostAddress, slotNumber, workStatus, doorStatus, 
-                    cardStatus, cardStatusChange, cardNumber, 
-                    faults, voltage, current, dataLength);
+            WorkStatus workStatus = parseWorkStatus(packetData, 7);
+            DoorStatus doorStatus = parseDoorStatus(packetData, 8);
+            CardStatus cardStatus = parseCardStatus(packetData, 9);
+            int cardStatusChange = parseCardStatusChange(packetData, 10);
+            String cardNumber = parseCardNumber(packetData, 13);
+            List<FaultType> faults = parseFaults(packetData, 15);
+            double voltage = parseVoltage(packetData, 16);
+            double current = parseCurrent(packetData, 17);
+
+            // 重用 ParseResult 对象
+            result.reset(hostAddress, slotNumber, workStatus, doorStatus, 
+                        cardStatus, cardStatusChange, cardNumber, 
+                        faults, voltage, current, dataLength);
+
+            return result;
 
         } catch (Exception e) {
+            // 发生异常时归还对象
+            ParseResultPool.returnObject(result);
             throw new RuntimeException("解析数据时发生错误: " + e.getMessage(), e);
         }
     }
 
     /**
-     * 保留原有方法用于兼容性
+     * 优化后的字符串解析方法
      */
     public static ParseResult parseDDCC01Data(String hexData) {
         if (hexData == null || hexData.isEmpty()) {
@@ -69,6 +80,7 @@
             throw new IllegalArgumentException("非DDCC协议数据");
         }
 
+        ParseResult result = ParseResultPool.borrowObject();
         try {
             // 1. 移除包头DDCC进行解析
             String dataWithoutHeader = hexData.substring(4);
@@ -79,178 +91,162 @@
             }
 
             // 2. 解析各个字段
-            int dataLength = parseDataLength(dataBytes);
-            int hostAddress = parseHostAddress(dataBytes);
-            int slotNumber = parseSlotNumber(dataBytes);
-            int functionCode = parseFunctionCode(dataBytes);
-            WorkStatus workStatus = parseWorkStatus(dataBytes);
-            DoorStatus doorStatus = parseDoorStatus(dataBytes);
-            CardStatus cardStatus = parseCardStatus(dataBytes);
-            int cardStatusChange = parseCardStatusChange(dataBytes);
-            String cardNumber = parseCardNumber(dataBytes);
-            List<FaultType> faults = parseFaults(dataBytes);
-            double voltage = parseVoltage(dataBytes);
-            double current = parseCurrent(dataBytes);
+            int dataLength = parseDataLength(dataBytes, 0);
+            int hostAddress = parseHostAddress(dataBytes, 2);
+            int slotNumber = parseSlotNumber(dataBytes, 3);
+            int functionCode = parseFunctionCode(dataBytes, 4);
 
             // 3. 验证功能码
             if (functionCode != 0x01) {
                 throw new IllegalArgumentException("非01功能码数据");
             }
 
-            return new ParseResult(hostAddress, slotNumber, workStatus, doorStatus, 
-                    cardStatus, cardStatusChange, cardNumber, 
-                    faults, voltage, current, dataLength);
+            WorkStatus workStatus = parseWorkStatus(dataBytes, 5);
+            DoorStatus doorStatus = parseDoorStatus(dataBytes, 6);
+            CardStatus cardStatus = parseCardStatus(dataBytes, 7);
+            int cardStatusChange = parseCardStatusChange(dataBytes, 8);
+            String cardNumber = parseCardNumber(dataBytes, 11);
+            List<FaultType> faults = parseFaults(dataBytes, 13);
+            double voltage = parseVoltage(dataBytes, 14);
+            double current = parseCurrent(dataBytes, 15);
+
+            result.reset(hostAddress, slotNumber, workStatus, doorStatus, 
+                        cardStatus, cardStatusChange, cardNumber, 
+                        faults, voltage, current, dataLength);
+
+            return result;
 
         } catch (Exception e) {
+            ParseResultPool.returnObject(result);
             throw new RuntimeException("解析数据时发生错误: " + e.getMessage(), e);
         }
     }
 
     /**
-     * CRC校验
-     * 根据协议:CRC16校验从功能码之后一直到CRC16之前的数据
-     */
-    private static boolean validateCRC(String hexData) {
-        try {
-            // CRC在最后4个字符
-            String receivedCRC = hexData.substring(hexData.length() - 6);
-            byte[] cmdBytes = HexUtil.hexStringToBytes(hexData.replace(receivedCRC,""));
-            String crc = HexUtil.calculate(cmdBytes)+"00"; 
-            System.out.println("收到的完整数据是:"+hexData);
-            System.out.println("收到数据校验码是:"+receivedCRC);
-            System.out.println("校验码是:"+crc);
-            return receivedCRC.equalsIgnoreCase(crc);            
-        } catch (Exception e) {
-            System.err.println("CRC校验异常: " + e.getMessage());
-            return false;
-        }
-    }
-
-    /**
      * 解析数据长度(2字节)
-     * 数据长度是从该字节之后开始到CRC16之前数据字节数
      */
-    private static int parseDataLength(byte[] data) {
-        if (data.length < 2) {
+    private static int parseDataLength(byte[] data, int offset) {
+        if (data.length < offset + 2) {
             throw new IllegalArgumentException("数据长度不足,无法解析数据长度");
         }
-        return ((data[0] & 0xFF) << 8) | (data[1] & 0xFF);
+        return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
     }
 
     /**
      * 解析主机地址(1字节)
      */
-    private static int parseHostAddress(byte[] data) {
-        if (data.length < 3) {
+    private static int parseHostAddress(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析主机地址");
         }
-        return data[2] & 0xFF;
+        return data[offset] & 0xFF;
     }
 
     /**
      * 解析卡槽编号(1字节)
      */
-    private static int parseSlotNumber(byte[] data) {
-        if (data.length < 4) {
+    private static int parseSlotNumber(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析卡槽编号");
         }
-        return data[3] & 0xFF;
+        return data[offset] & 0xFF;
     }
 
     /**
      * 解析功能码(1字节)
      */
-    private static int parseFunctionCode(byte[] data) {
-        if (data.length < 5) {
+    private static int parseFunctionCode(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析功能码");
         }
-        return data[4] & 0xFF;
+        return data[offset] & 0xFF;
     }
 
     /**
      * 解析工作状态(1字节)
      */
-    private static WorkStatus parseWorkStatus(byte[] data) {
-        if (data.length < 6) {
+    private static WorkStatus parseWorkStatus(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析工作状态");
         }
-        int statusValue = data[5] & 0xFF;
+        int statusValue = data[offset] & 0xFF;
         return WorkStatus.fromValue(statusValue);
     }
 
     /**
      * 解析在位状态/门状态(1字节)
      */
-    private static DoorStatus parseDoorStatus(byte[] data) {
-        if (data.length < 7) {
+    private static DoorStatus parseDoorStatus(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析在位状态");
         }
-        int statusValue = data[6] & 0xFF;
+        int statusValue = data[offset] & 0xFF;
         return DoorStatus.fromValue(statusValue);
     }
 
     /**
      * 解析卡状态(1字节)
      */
-    private static CardStatus parseCardStatus(byte[] data) {
-        if (data.length < 8) {
+    private static CardStatus parseCardStatus(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析卡状态");
         }
-        int statusValue = data[7] & 0xFF;
+        int statusValue = data[offset] & 0xFF;
         return CardStatus.fromValue(statusValue);
     }
 
     /**
      * 解析卡状态变更(1字节)
      */
-    private static int parseCardStatusChange(byte[] data) {
-        if (data.length < 9) {
+    private static int parseCardStatusChange(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析卡状态变更");
         }
-        return data[8] & 0xFF;
+        return data[offset] & 0xFF;
     }
 
     /**
      * 解析卡号(卡号3 + 卡号4)
      */
-    private static String parseCardNumber(byte[] data) {
-        if (data.length < 13) {
+    private static String parseCardNumber(byte[] data, int offset) {
+        if (data.length < offset + 2) {
             throw new IllegalArgumentException("数据长度不足,无法解析卡号");
         }
-        // 索引11:卡号3,索引12:卡号4
-        byte cardNumber3 = data[11];
-        byte cardNumber4 = data[12];
-
-        return String.format("%02X%02X", cardNumber3 & 0xFF, cardNumber4 & 0xFF);
+        // 直接返回字符串,避免创建临时对象
+        char[] hexChars = new char[4];
+        hexChars[0] = Character.forDigit((data[offset] >> 4) & 0xF, 16);
+        hexChars[1] = Character.forDigit(data[offset] & 0xF, 16);
+        hexChars[2] = Character.forDigit((data[offset + 1] >> 4) & 0xF, 16);
+        hexChars[3] = Character.forDigit(data[offset + 1] & 0xF, 16);
+        return new String(hexChars).toUpperCase();
     }
 
     /**
      * 解析故障信息(1字节)
      */
-    private static List<FaultType> parseFaults(byte[] data) {
-        if (data.length < 14) {
+    private static List<FaultType> parseFaults(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析故障信息");
         }
-        int faultByte = data[13] & 0xFF;
-        List<FaultType> faults = new ArrayList<>();
-
+        int faultByte = data[offset] & 0xFF;
+        List<FaultType> faults = new ArrayList<>(5); // 预分配容量
+        
         for (FaultType fault : FaultType.values()) {
             if ((faultByte & fault.getBitMask()) != 0) {
                 faults.add(fault);
             }
         }
-
         return faults;
     }
 
     /**
      * 解析电压值(1字节)
      */
-    private static double parseVoltage(byte[] data) {
-        if (data.length < 15) {
+    private static double parseVoltage(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析电压");
         }
-        int voltageValue = data[14] & 0xFF;
+        int voltageValue = data[offset] & 0xFF;
         // 50mV/bit 转换为伏特
         return voltageValue * 0.05;
     }
@@ -258,18 +254,16 @@
     /**
      * 解析电流值(1字节)
      */
-    private static double parseCurrent(byte[] data) {
-        if (data.length < 16) {
+    private static double parseCurrent(byte[] data, int offset) {
+        if (data.length < offset + 1) {
             throw new IllegalArgumentException("数据长度不足,无法解析电流");
         }
-        int currentValue = data[15] & 0xFF;
+        int currentValue = data[offset] & 0xFF;
         // 10mA/bit 转换为安培
         return currentValue * 0.01;
     }
 
-    /**
-     * 工作状态枚举
-     */
+    // 枚举类保持不变...
     public enum WorkStatus {
         INVALID(0, "无效"),
         STANDBY(1, "待机"),
@@ -288,13 +282,8 @@
             this.description = description;
         }
 
-        public int getValue() {
-            return value;
-        }
-
-        public String getDescription() {
-            return description;
-        }
+        public int getValue() { return value; }
+        public String getDescription() { return description; }
 
         public static WorkStatus fromValue(int value) {
             for (WorkStatus status : values()) {
@@ -306,9 +295,6 @@
         }
     }
 
-    /**
-     * 门状态枚举
-     */
     public enum DoorStatus {
         UNKNOWN(0, "未知状态"),
         DOOR_OPEN(1, "开门状态"),
@@ -322,13 +308,8 @@
             this.description = description;
         }
 
-        public int getValue() {
-            return value;
-        }
-
-        public String getDescription() {
-            return description;
-        }
+        public int getValue() { return value; }
+        public String getDescription() { return description; }
 
         public static DoorStatus fromValue(int value) {
             for (DoorStatus status : values()) {
@@ -340,9 +321,6 @@
         }
     }
 
-    /**
-     * 卡状态枚举
-     */
     public enum CardStatus {
         NO_CARD(0, "无卡"),
         HAS_CARD(1, "有卡"),
@@ -357,13 +335,8 @@
             this.description = description;
         }
 
-        public int getValue() {
-            return value;
-        }
-
-        public String getDescription() {
-            return description;
-        }
+        public int getValue() { return value; }
+        public String getDescription() { return description; }
 
         public static CardStatus fromValue(int value) {
             for (CardStatus status : values()) {
@@ -375,9 +348,6 @@
         }
     }
 
-    /**
-     * 故障类型枚举
-     */
     public enum FaultType {
         INSERT_ERROR(0x01, "插卡错误"),
         OVER_CURRENT(0x02, "过流"),
@@ -393,17 +363,12 @@
             this.description = description;
         }
 
-        public int getBitMask() {
-            return bitMask;
-        }
-
-        public String getDescription() {
-            return description;
-        }
+        public int getBitMask() { return bitMask; }
+        public String getDescription() { return description; }
     }
 
     /**
-     * 解析结果类 - 添加对象池支持
+     * 优化后的解析结果类
      */
     public static class ParseResult {
         private int hostAddress;
@@ -418,29 +383,12 @@
         private double current;
         private int dataLength;
 
-        // 默认构造器用于对象池
+        // 重用列表对象
+        private final List<FaultType> faultList = new ArrayList<>(5);
+        private final List<String> faultDescList = new ArrayList<>(5);
+
         public ParseResult() {}
 
-        public ParseResult(int hostAddress, int slotNumber, WorkStatus workStatus, 
-                DoorStatus doorStatus, CardStatus cardStatus, int cardStatusChange,
-                String cardNumber, List<FaultType> faults, double voltage, 
-                double current, int dataLength) {
-            this.hostAddress = hostAddress;
-            this.slotNumber = slotNumber;
-            this.workStatus = workStatus;
-            this.doorStatus = doorStatus;
-            this.cardStatus = cardStatus;
-            this.cardStatusChange = cardStatusChange;
-            this.cardNumber = cardNumber;
-            this.faults = faults;
-            this.voltage = voltage;
-            this.current = current;
-            this.dataLength = dataLength;
-        }
-
-        /**
-         * 重置方法,用于对象重用
-         */
         public void reset(int hostAddress, int slotNumber, WorkStatus workStatus, 
                          DoorStatus doorStatus, CardStatus cardStatus, int cardStatusChange,
                          String cardNumber, List<FaultType> faults, double voltage, 
@@ -452,10 +400,16 @@
             this.cardStatus = cardStatus;
             this.cardStatusChange = cardStatusChange;
             this.cardNumber = cardNumber;
-            this.faults = faults;
             this.voltage = voltage;
             this.current = current;
             this.dataLength = dataLength;
+            
+            // 重用故障列表
+            this.faultList.clear();
+            if (faults != null) {
+                this.faultList.addAll(faults);
+            }
+            this.faults = this.faultList;
         }
 
         // Getter方法
@@ -475,21 +429,24 @@
          * 获取故障的中文描述列表
          */
         public List<String> getFaultDescriptions() {
-            List<String> descriptions = new ArrayList<>();
+            faultDescList.clear();
             for (FaultType fault : faults) {
-                descriptions.add(fault.getDescription());
+                faultDescList.add(fault.getDescription());
             }
-            return descriptions;
+            return faultDescList;
         }
 
         /**
          * 获取故障的中文描述字符串
          */
         public String getFaultsString() {
-            if (faults == null || faults.isEmpty()) {
+            if (faults.isEmpty()) {
                 return "无故障";
             }
-            StringBuilder sb = new StringBuilder();
+            
+            StringBuilder sb = stringBuilderPool.get();
+            sb.setLength(0);
+            
             for (int i = 0; i < faults.size(); i++) {
                 if (i > 0) sb.append(", ");
                 sb.append(faults.get(i).getDescription());
@@ -499,49 +456,47 @@
 
         @Override
         public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append("=== DDCC协议数据解析结果 ===\n");
-            sb.append("1. 主机地址: ").append(String.format("%02X", hostAddress));
-            sb.append("2. 卡槽编号: ").append(slotNumber);
-            sb.append("3. 工作状态: ").append(workStatus.getDescription())
-              .append(" (").append(workStatus.getValue());
-            sb.append("4. 门状态: ").append(doorStatus.getDescription())
-              .append(" (").append(doorStatus.getValue());
-            sb.append("5. 卡状态: ").append(cardStatus.getDescription())
-              .append(" (").append(cardStatus.getValue());
-            sb.append("6. 卡状态变更: ").append(cardStatusChange);
-            sb.append("7. 卡号: ").append(cardNumber);
-            sb.append("8. 故障: ").append(getFaultsString());
-            sb.append("9. 电压: ").append(String.format("%.2f", voltage));
-            sb.append("10. 电流: ").append(String.format("%.2f", current));
-            sb.append("数据长度: ").append(dataLength).append(" 字节"); 
-//            System.out.println(sb.toString());
-            return sb.toString();           
+            StringBuilder sb = stringBuilderPool.get();
+            sb.setLength(0);
+            
+            sb.append("1.主机地址:").append(String.format("%02X", hostAddress));
+            sb.append("2.卡槽编号:").append(slotNumber);
+            sb.append("3.工作状态:").append(workStatus.getDescription())
+              .append("(").append(workStatus.getValue()).append(")");
+            sb.append("4. 门状态:").append(doorStatus.getDescription())
+              .append("(").append(doorStatus.getValue()).append(")");
+            sb.append("5.卡状态:").append(cardStatus.getDescription())
+              .append("(").append(cardStatus.getValue()).append(")");
+            sb.append("6.卡状态变更:").append(cardStatusChange);
+            sb.append("7.卡号:").append(cardNumber);
+            sb.append("8.故障:").append(getFaultsString());
+            sb.append("9.电压:").append(String.format("%.2f", voltage));
+            sb.append("10.电流:").append(String.format("%.2f", current));
+            sb.append("数据长度:").append(dataLength).append(" 字节");
+            
+            return sb.toString();
         }
         
         public void fuzhi() {
-        	SlotManager.gengxinshuxingzhi(            		
+            SlotManager.gengxinshuxingzhi(            		
                     slotNumber,    // 卡槽编号
                     cardNumber,    // 卡编号
                     String.valueOf(cardStatus.getValue()),       // 是否有卡0无卡,1有卡,-1未知
-                    String.valueOf(workStatus.getValue()),    // 工作状态0.无效1.待机;2.充电;3.充满;4.故障;5.授权到期;6.通信超时
+                    String.valueOf(workStatus.getValue()),    // 工作状态
                     String.format("%.2f", voltage),      // 电压
                     String.format("%.2f", current),       // 电流
-                    getFaultsString()        // 故障1插卡错误;2过流;3,门控故障;4过压;5欠压;
-                    );  
-        	
-        	
-        	
+                    getFaultsString()        // 故障
+            );  
         }
     }
-    
+
     /**
-     * 简单的对象池实现
+     * 改进的对象池实现
      */
     public static class ParseResultPool {
-        private static final int POOL_SIZE = 10;
+        private static final int POOL_SIZE = 20;
         private static final java.util.concurrent.BlockingQueue<ParseResult> pool = 
-            new java.util.concurrent.ArrayBlockingQueue<>(POOL_SIZE);
+            new java.util.concurrent.LinkedBlockingQueue<>(POOL_SIZE);
         
         static {
             // 预创建对象
@@ -556,9 +511,17 @@
         }
         
         public static void returnObject(ParseResult result) {
-            if (result != null && !pool.offer(result)) {
-                // 池已满,不回收
+            if (result != null) {
+                // 清理状态
+                result.reset(0, 0, WorkStatus.UNKNOWN, DoorStatus.UNKNOWN, 
+                           CardStatus.UNKNOWN, 0, "", null, 0.0, 0.0, 0);
+                // 非阻塞式归还
+                pool.offer(result);
             }
         }
+        
+        public static int getPoolSize() {
+            return pool.size();
+        }
     }
 }
\ No newline at end of file

--
Gitblit v1.9.3