| | |
| | | import java.util.List; |
| | | 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) { |
| | |
| | | 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()) { |
| | |
| | | throw new IllegalArgumentException("非DDCC协议数据"); |
| | | } |
| | | |
| | | ParseResult result = ParseResultPool.borrowObject(); |
| | | try { |
| | | // 1. 移除包头DDCC进行解析 |
| | | String dataWithoutHeader = hexData.substring(4); |
| | |
| | | } |
| | | |
| | | // 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; |
| | | } |
| | |
| | | /** |
| | | * 解析电流值(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, "待机"), |
| | |
| | | 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()) { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 门状态枚举 |
| | | */ |
| | | public enum DoorStatus { |
| | | UNKNOWN(0, "δ֪״̬"), |
| | | DOOR_OPEN(1, "开门状态"), |
| | |
| | | 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()) { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 卡状态枚举 |
| | | */ |
| | | public enum CardStatus { |
| | | NO_CARD(0, "无卡"), |
| | | HAS_CARD(1, "有卡"), |
| | |
| | | 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()) { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 故障类型枚举 |
| | | */ |
| | | public enum FaultType { |
| | | INSERT_ERROR(0x01, "插卡错误"), |
| | | OVER_CURRENT(0x02, "过流"), |
| | |
| | | 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; |
| | |
| | | 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, |
| | |
| | | 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方法 |
| | |
| | | * 获取故障的中文描述列表 |
| | | */ |
| | | 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()); |
| | |
| | | |
| | | @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 { |
| | | // 预创建对象 |
| | |
| | | } |
| | | |
| | | 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(); |
| | | } |
| | | } |
| | | } |