diff --git a/src/main/java/com/qgs/dc/s7/controller/S7DemoController.java b/src/main/java/com/qgs/dc/s7/controller/S7DemoController.java index 315a2d2..c8796d9 100644 --- a/src/main/java/com/qgs/dc/s7/controller/S7DemoController.java +++ b/src/main/java/com/qgs/dc/s7/controller/S7DemoController.java @@ -1,16 +1,13 @@ package com.qgs.dc.s7.controller; -import com.influxdb.client.InfluxDBClient; -import com.influxdb.client.domain.WritePrecision; -import com.influxdb.client.write.Point; import com.qgs.dc.opcua.controller.R; import com.qgs.dc.s7.entity.AGVInfoCallBack; import com.qgs.dc.s7.my.s7connector.enmuc.PlcVarActual; + + import com.qgs.dc.s7.my.s7connector.enmuc.S7Client; - - import com.qgs.dc.s7.my.s7connector.type.PlcVar; import org.slf4j.Logger; @@ -154,7 +151,7 @@ public class S7DemoController { public R testForString1200() throws Exception { //测试结果 l => 66ms long l = System.currentTimeMillis(); - String[] subs = (String[])read(S7Client.S7_1200,PlcVarActual.SubIdArrays1200); //65ms + String[] subs = (String[])read(S7Client.S7_1500,PlcVarActual.SubIdArrays1200); //65ms long l1 = System.currentTimeMillis(); //System.out.println(Arrays.toString(subs)); @@ -165,10 +162,10 @@ public class S7DemoController { } ////测试结果 c => 57ms long c1 = System.currentTimeMillis(); - write(S7Client.S7_1200,PlcVarActual.SubIdArrays1200,toWrite); + write(S7Client.S7_1500,PlcVarActual.SubIdArrays1200,toWrite); long c2 = System.currentTimeMillis(); - String[] subs2 = (String[])read(S7Client.S7_1200,PlcVarActual.SubIdArrays1200); + String[] subs2 = (String[])read(S7Client.S7_1500,PlcVarActual.SubIdArrays1200); logger.info("正常测试: l:"+(l1-l)+"c:"+(c2-c1)+";;read1:"+Arrays.toString(subs)+";;read2:"+Arrays.toString(subs2)); return R.ok().put("l",(l1-l)).put("c",(c2-c1)); @@ -202,17 +199,17 @@ public class S7DemoController { @PostMapping("/testFor1200") public R testFor1200() throws Exception { - //Object subs = read(PlcVarActual.INT1200, S7Client.S7_1200); - Object read = read(S7Client.S7_1200, PlcVarActual.SubIdArrays1200); + //Object subs = read(PlcVarActual.INT1200, S7Client.S7_1500); + Object read = read(S7Client.S7_1500, PlcVarActual.SubIdArrays1200); String[] toWrite = new String[60]; for(int i=0;i<60;i++){ int i1 = new Random().nextInt(100); toWrite[i] = "2212"+ i1; } - write(S7Client.S7_1200,PlcVarActual.SubIdArrays1200,toWrite); + write(S7Client.S7_1500,PlcVarActual.SubIdArrays1200,toWrite); - Object read2 = read(S7Client.S7_1200, PlcVarActual.SubIdArrays1200); + Object read2 = read(S7Client.S7_1500, PlcVarActual.SubIdArrays1200); return R.ok(); } diff --git a/src/main/java/com/qgs/dc/s7/my/s7connector/MainForRead.java b/src/main/java/com/qgs/dc/s7/my/s7connector/MainForRead.java index b19382e..1a14656 100644 --- a/src/main/java/com/qgs/dc/s7/my/s7connector/MainForRead.java +++ b/src/main/java/com/qgs/dc/s7/my/s7connector/MainForRead.java @@ -1,15 +1,6 @@ package com.qgs.dc.s7.my.s7connector; -import com.qgs.dc.common.utils.CommonFunction; -import com.qgs.dc.s7.my.s7connector.api.DaveArea; -import com.qgs.dc.s7.my.s7connector.api.S7Connector; -import com.qgs.dc.s7.my.s7connector.api.utils.ByteUtils; -import com.qgs.dc.s7.my.s7connector.enmuc.S7Client; - import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.List; /** * @Desc: "" diff --git a/src/main/java/com/qgs/dc/s7/my/s7connector/MainForReadDemo.java b/src/main/java/com/qgs/dc/s7/my/s7connector/MainForReadDemo.java index ebcdfd9..45ae1dd 100644 --- a/src/main/java/com/qgs/dc/s7/my/s7connector/MainForReadDemo.java +++ b/src/main/java/com/qgs/dc/s7/my/s7connector/MainForReadDemo.java @@ -4,11 +4,6 @@ import com.qgs.dc.s7.my.s7connector.api.DaveArea; import com.qgs.dc.s7.my.s7connector.api.S7Connector; import com.qgs.dc.s7.my.s7connector.api.utils.ByteUtils; import com.qgs.dc.s7.my.s7connector.enmuc.S7Client; -import com.qgs.dc.s7.my.s7connector.type.PlcVar; - -import java.io.UnsupportedEncodingException; -import java.util.List; - /** diff --git a/src/main/java/com/qgs/dc/s7/my/s7connector/api/S7Connector.java b/src/main/java/com/qgs/dc/s7/my/s7connector/api/S7Connector.java index e7f9413..3f5e071 100644 --- a/src/main/java/com/qgs/dc/s7/my/s7connector/api/S7Connector.java +++ b/src/main/java/com/qgs/dc/s7/my/s7connector/api/S7Connector.java @@ -23,7 +23,7 @@ import java.io.Closeable; public interface S7Connector extends Closeable { /** * Reads an area - * desc : 只要未抛出异常,都是 操作成功的 + * desc : 只要未抛出异常,都是 操作成功的 ( 锁 ) * @param area * @param areaNumber * @param bytes @@ -34,7 +34,7 @@ public interface S7Connector extends Closeable { /** * Reads an area 读需要bit 位置的 变量(其实就是 read bool变量的时候调用这个方法。) - * desc : 只要未抛出异常,都是 操作成功的 + * desc : 只要未抛出异常,都是 操作成功的 ( 锁 ) * @param area * @param areaNumber * @param bytes @@ -44,7 +44,7 @@ public interface S7Connector extends Closeable { public byte[] read(DaveArea area, int areaNumber, int bytes, int offset, int bitOffset, TransportSize transportSize); /** * Writes an area - * desc : 只要未抛出异常,都是 操作成功的 + * desc : 只要未抛出异常,都是 操作成功的 ( 锁 ) * @param area * @param areaNumber * @param offset @@ -52,7 +52,7 @@ public interface S7Connector extends Closeable { */ public void write(DaveArea area, int areaNumber, int offset, byte[] buffer); - //如果 bitOffset 没有 那么就填0 + //如果 bitOffset 没有 那么就填0 ( 锁 ) public void write(DaveArea area, int areaNumber, int byteOffset, int bitOffset, byte[] buffer, PlcVar var); } diff --git a/src/main/java/com/qgs/dc/s7/my/s7connector/enmuc/S7Client.java b/src/main/java/com/qgs/dc/s7/my/s7connector/enmuc/S7Client.java index 74d81ad..a04d7fe 100644 --- a/src/main/java/com/qgs/dc/s7/my/s7connector/enmuc/S7Client.java +++ b/src/main/java/com/qgs/dc/s7/my/s7connector/enmuc/S7Client.java @@ -8,12 +8,11 @@ import com.qgs.dc.s7.my.s7connector.api.utils.ByteUtils; import com.qgs.dc.s7.my.s7connector.exception.S7Exception; import com.qgs.dc.s7.my.s7connector.type.PlcVar; import com.qgs.dc.s7.my.s7connector.utils.CommonFunctions; +import com.qgs.dc.s7.retry.S7RetryTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; /** @@ -24,14 +23,11 @@ import java.util.concurrent.ScheduledExecutorService; public enum S7Client { //TODO 步骤1 这里是配置多PLC 的,,,有多个plc 就在这里配置一个枚举类 //1500 西门子200smart、1200、1500默认的 机架号=0 槽位号=1; 300/400 默认的 机架-0 插槽-2 - S7_1200("192.168.0.52",0,1,1,PlcVarActual.HeartBeatFor1200), - +// S7_1200("192.168.0.52",0,1,1,PlcVarActual.HeartBeatFor1200), + S7_15001("192.168.0.51",0,1,1,PlcVarActual.HeartBeat), S7_1500("192.168.0.51",0,1,1,PlcVarActual.HeartBeat), //1500 机架-0 插槽-1 //后续 在这里扩展 多PLC应用。 - - - ; private String host; //默认 0 机架号 @@ -49,27 +45,21 @@ public enum S7Client { private int pickOne; private static final Logger logger = LoggerFactory.getLogger(S7Client.class); - private ScheduledExecutorService executor; - private ScheduledExecutorService ping_fail_check; + + //coreSize 是线程池的数量 - S7Client(String host, Integer rack, Integer slot,Integer coreSize,PlcVarActual heartBeat){ + S7Client(String host, Integer rack, Integer slot, Integer coreSize, PlcVarActual heartBeat){ this.host = host; this.rack = rack; this.slot = slot; this.pickOne = 0; - this.executor = Executors.newScheduledThreadPool(1); - this.ping_fail_check = Executors.newScheduledThreadPool(1); - this.coreSize = coreSize; - this.heartBeat = heartBeat; + connections = new ArrayList<>(); connectionPool(); - ping(); -// - check_ping(); } public String getHost(){ @@ -112,73 +102,87 @@ public enum S7Client { * UDIntArray ===> List * StringArray ===> String[] (特殊) * - * + * 如果返回null,就代表出现了异常,并且尝试了 retryMax 次数,并且尝试重置连接 * */ - public Object read(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset, Integer length, Integer strSizes, PlcVar type) throws Exception { + public Object read(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset, Integer length, Integer strSizes, PlcVar type) { S7Connector connector = getConnector(); - //String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。 - if(type.equals(PlcVar.STRING)){ - Integer readBytes = 2; - byte[] read = connector.read( - area, - areaNumber, - readBytes, - byteOffset, - bitOffset, - type.getTransportSize() - ); + return S7RetryTemplate.getInstance().execute( + context -> { + //String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。 + if(type.equals(PlcVar.STRING)){ + Integer readBytes = 2; + byte[] read = connector.read( + area, + areaNumber, + readBytes, + byteOffset, + bitOffset, + type.getTransportSize() + ); - Integer allLength = Integer.valueOf(read[1])+2; - byte[] readF = connector.read( - area, - areaNumber, - allLength, - byteOffset, - bitOffset, - type.getTransportSize() - ); - return type.toObject(readF); - }else if(type.equals(PlcVar.BOOL_Array)){ + Integer allLength = Integer.valueOf(read[1])+2; + byte[] readF = connector.read( + area, + areaNumber, + allLength, + byteOffset, + bitOffset, + type.getTransportSize() + ); + return type.toObject(readF); + }else if(type.equals(PlcVar.BOOL_Array)){ - byte[] read = connector.read( - area, - areaNumber, - CommonFunctions.exactDivision(length,8), - byteOffset, - bitOffset, - type.getTransportSize() - ); - List booleans = ByteUtils.toBoolArray(read); - List res = new ArrayList(); - for(int i=0;i booleans = ByteUtils.toBoolArray(read); + List res = new ArrayList(); + for(int i=0;i { + logger.info("S7-Retry : 已达到最大重试次数: "+S7RetryTemplate.getMaxRetryTimes()+", 现在尝试重新连接"+" ; 异常原因 : "+context.getLastThrowable().getMessage()); + if(replaceConnector(connector)==1){ + logger.info("S7-Retry-Read 现在恢复成功,创建新connection成功"); + return null; + }else { + logger.info("S7-Retry-Read 现在恢复失败,创建新connection失败"); + return null; + } + } + ); } @@ -228,53 +232,103 @@ public enum S7Client { * * * */ - public void write(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset,Integer strSize, PlcVar type, Object newValue) throws Exception { + public void write(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset,Integer strSize, PlcVar type, Object newValue) { S7Connector connector = getConnector(); - //String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。 - if(type.equals(PlcVar.STRING)){ - connector.write( - area, - areaNumber, - byteOffset, - bitOffset, - ByteUtils.strToBytes(newValue.toString(), strSize), - type - ); - }else if(type.equals(PlcVar.BOOL_Array)){ - connector.write( - area, - areaNumber, - byteOffset, - bitOffset, - ByteUtils.toByteArray((boolean[])newValue), - type - ); - }else if(type.equals(PlcVar.STRING_Array)){ - //todo here 检查 read write service - connector.write( - area, - areaNumber, - byteOffset, - bitOffset, - ByteUtils.strArrayToBytes((String[])newValue, strSize), - type - ); - }else { - byte[] bytes = type.toBytes(newValue); - connector.write( - area, - areaNumber, - byteOffset, - bitOffset, - bytes, - type - ); - } + S7RetryTemplate.getInstance().execute( + context -> { + //String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。 + if(type.equals(PlcVar.STRING)){ + connector.write( + area, + areaNumber, + byteOffset, + bitOffset, + ByteUtils.strToBytes(newValue.toString(), strSize), + type + ); + }else if(type.equals(PlcVar.BOOL_Array)){ + connector.write( + area, + areaNumber, + byteOffset, + bitOffset, + ByteUtils.toByteArray((boolean[])newValue), + type + ); + }else if(type.equals(PlcVar.STRING_Array)){ + //todo here 检查 read write service + connector.write( + area, + areaNumber, + byteOffset, + bitOffset, + ByteUtils.strArrayToBytes((String[])newValue, strSize), + type + ); + }else { + byte[] bytes = type.toBytes(newValue); + connector.write( + area, + areaNumber, + byteOffset, + bitOffset, + bytes, + type + ); + } + return null; + }, + context -> { + logger.info("S7-Retry-Write : 已达到最大重试次数: "+S7RetryTemplate.getMaxRetryTimes()+", 现在尝试重新连接"); + if( replaceConnector(connector) == 1 ){ + logger.info("S7-Retry-Write 现在恢复成功,创建新connection成功"); + return null; + }else { + logger.info("S7-Retry-Write 现在恢复失败,创建新connection失败"); + return null; + } + } + ); } +// public void retry1() throws InterruptedException { +// S7RetryTemplate instance = S7RetryTemplate.getInstance(); +// System.out.println(instance.hashCode()+ ", "+Thread.currentThread().getName()); +// instance.execute( +// retryContext -> { +// System.out.println("retry1 : " + Thread.currentThread().getName() ); +// Thread.sleep(10000); +// System.out.println("retry1 sleepdown : " + Thread.currentThread().getName() ); +// return true; +// }, +// retryContext -> { +// System.out.println("retry1 err: " + Thread.currentThread().getName() ); +// return false; +// } +// ); +// } - public S7Connector getConnector() { + /** + * desc: 传入的connection 是需要被替换的 + * return: + * 1 代表替换成功 + * -1 代表替换失败(创建connection失败,原因:出现异常.原来的connection也被舍弃掉了) + * */ + private synchronized Integer replaceConnector(S7Connector oldOne){ + connections.remove(oldOne); + S7Connector connect = connect(host, rack, slot); + if(connect == null){ + return -1; + }else { + connections.add(connect); + return 1; + } + + } + + //虽然是枚举类,但这个是对象锁(不是类锁) + public synchronized S7Connector getConnector() { int size = connections.size(); S7Connector s7Connector = connections.get((pickOne + size) % size); pickOne+=1; @@ -282,7 +336,9 @@ public enum S7Client { return s7Connector; } - private S7Connector connect(String host,Integer rack,Integer slot ){ + + + private synchronized S7Connector connect(String host,Integer rack,Integer slot ){ try { S7Connector connector = S7ConnectorFactory .buildTCPConnector() @@ -303,7 +359,7 @@ public enum S7Client { connectionPool(); } - private void connectionPool(){ + private synchronized void connectionPool(){ for(int i=0;i connections; - //coreSize 是线程池的大小 - private Integer coreSize; - //pickOne 就是一个初始化 的轮询取余值 - private int pickOne; - private static final Logger logger = LoggerFactory.getLogger(S7ClientNew.class); - - - - - //coreSize 是线程池的数量 - S7ClientNew(String host, Integer rack, Integer slot, Integer coreSize, PlcVarActual heartBeat){ - this.host = host; - this.rack = rack; - this.slot = slot; - this.pickOne = 0; - - this.coreSize = coreSize; - - connections = new ArrayList<>(); - connectionPool(); - - } - - public String getHost(){ - return this.host; - } - - /** - * PlcVar(byte[]) 转 java对象 对照表 - * 单体变量 - * Bool ===> Boolean - * LREAL ===> Double - * REAL ===> Float - * DATE ===> String(yyyy-MM-dd 这种形式的类型) - * DTL ===> String("年-月-日-工作日-时-分-秒" 这种格式) - * TIME ===> Integer(单位 ms) - * USINT ===> Integer - * SINT ===> Integer - * UINT ===> Integer - * INT ===> Integer - * DINT ===> Integer - * UINT ===> Long - * Byte ===> Integer(有符号)(默认) - * Integer(无符号)(后续扩展) - * Char ===> Character - * WChar ===> Character - * String ===> String (特殊) - - - * 数组变量 - * BoolArray ===> List - * ByteArray ===> List - * WordArray ===> List - * DWordArray ===> List - * CharArray ===> List - * SIntArray ===> List - * IntArray ===> List - * DIntArray ===> List - * UIntArray ===> List - * USIntArray ===> List - * UDIntArray ===> List - * StringArray ===> String[] (特殊) - * - * 如果返回null,就代表出现了异常,并且尝试了 retryMax 次数,并且尝试重置连接 - * */ - public Object read(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset, Integer length, Integer strSizes, PlcVar type) { - S7Connector connector = getConnector(); - return S7RetryTemplate.getInstance().execute( - context -> { - //String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。 - if(type.equals(PlcVar.STRING)){ - Integer readBytes = 2; - byte[] read = connector.read( - area, - areaNumber, - readBytes, - byteOffset, - bitOffset, - type.getTransportSize() - ); - - Integer allLength = Integer.valueOf(read[1])+2; - byte[] readF = connector.read( - area, - areaNumber, - allLength, - byteOffset, - bitOffset, - type.getTransportSize() - ); - return type.toObject(readF); - }else if(type.equals(PlcVar.BOOL_Array)){ - - byte[] read = connector.read( - area, - areaNumber, - CommonFunctions.exactDivision(length,8), - byteOffset, - bitOffset, - type.getTransportSize() - ); - List booleans = ByteUtils.toBoolArray(read); - List res = new ArrayList(); - for(int i=0;i { - logger.info("S7-Retry : 已达到最大重试次数: "+S7RetryTemplate.getMaxRetryTimes()+", 现在尝试重新连接"); - if(replaceConnector(connector)==1){ - logger.info("S7-Retry-Read 现在恢复成功,创建新connection成功"); - return null; - }else { - logger.info("S7-Retry-Read 现在恢复失败,创建新connection失败"); - return null; - } - } - ); - } - - - - /** - * - * eg : - * Object newValue = Boolean.FALSE - * s7Service.write(PlcVarActual.HeartBeat, newValue, S7Client.S7_1200); - * - * PlcVar(byte[]) 转 java对象 对照表 - * 单体变量 - * Bool ===> Object newValue = Boolean.FALSE - * LREAL ===> Object newValue = Boolean.FALSE - * REAL ===> Object newValue = Boolean.FALSE - * DATE ===> 暂时没需求(有问题找我) - * DTL ===> 暂时没需求(有问题找我) - * TIME ===> 暂时没需求(有问题找我) - * USINT ===> Object newValue = new Integer(1) - * SINT ===> Object newValue = new Integer(1) - * UINT ===> Object newValue = new Integer(1) - * INT ===> Object newValue = new Integer(1) - * DINT ===> Object newValue = new Integer(1) - * UINT ===> Object newValue = new Integer(1) - * Byte ===> Object newValue = 0x11 - * - * Char ===> Object newValue = 'a' - * WChar ===> Object newValue = '菜' - * String ===> Object newValue = '你好啊' (特殊) - - - * 数组变量 - * 注意:在write的时候,你write的数量 一定要和 plc中存在的数量一一对应 - * BoolArray ===> boolean[] booleanArray = new boolean[2]; .... 赋予值 - * ByteArray ===> byte[] write_byteArrays = new byte[2]; - * WordArray ===> short[] shortArrays_content = new short[2]; - * DWordArray ===> int[] intArrays_content = new int[2]; - * CharArray ===> char[] charArrays_content = new char[2]; - * SIntArray ===> int[] sintArrays_content = new int[2]; - * IntArray ===> int[] iintArrays_content = new int[2]; - * DIntArray ===> int[] dintArrays_content = new int[2]; - * UIntArray ===> int[] uintArrays_content = new int[3]; - * USIntArray ===> int[] usintArrays_content = new int[3]; - * UDIntArray ===> int[] udintArrays_content = new int[3]; - * StringArray ===> String[] stringArrays_content = new String[3]; - * //如果有其他数据类型 这里没有找我扩展 - * - * - * */ - public void write(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset,Integer strSize, PlcVar type, Object newValue) { - S7Connector connector = getConnector(); - - S7RetryTemplate.getInstance().execute( - context -> { - //String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。 - if(type.equals(PlcVar.STRING)){ - connector.write( - area, - areaNumber, - byteOffset, - bitOffset, - ByteUtils.strToBytes(newValue.toString(), strSize), - type - ); - }else if(type.equals(PlcVar.BOOL_Array)){ - connector.write( - area, - areaNumber, - byteOffset, - bitOffset, - ByteUtils.toByteArray((boolean[])newValue), - type - ); - }else if(type.equals(PlcVar.STRING_Array)){ - //todo here 检查 read write service - connector.write( - area, - areaNumber, - byteOffset, - bitOffset, - ByteUtils.strArrayToBytes((String[])newValue, strSize), - type - ); - }else { - byte[] bytes = type.toBytes(newValue); - connector.write( - area, - areaNumber, - byteOffset, - bitOffset, - bytes, - type - ); - } - return null; - }, - context -> { - logger.info("S7-Retry-Write : 已达到最大重试次数: "+S7RetryTemplate.getMaxRetryTimes()+", 现在尝试重新连接"); - if( replaceConnector(connector) == 1 ){ - logger.info("S7-Retry-Write 现在恢复成功,创建新connection成功"); - return null; - }else { - logger.info("S7-Retry-Write 现在恢复失败,创建新connection失败"); - return null; - } - } - ); - } - -// public void retry1() throws InterruptedException { -// S7RetryTemplate instance = S7RetryTemplate.getInstance(); -// System.out.println(instance.hashCode()+ ", "+Thread.currentThread().getName()); -// instance.execute( -// retryContext -> { -// System.out.println("retry1 : " + Thread.currentThread().getName() ); -// Thread.sleep(10000); -// System.out.println("retry1 sleepdown : " + Thread.currentThread().getName() ); -// return true; -// }, -// retryContext -> { -// System.out.println("retry1 err: " + Thread.currentThread().getName() ); -// return false; -// } -// ); -// } - - /** - * desc: 传入的connection 是需要被替换的 - * return: - * 1 代表替换成功 - * -1 代表替换失败(创建connection失败,原因:出现异常.原来的connection也被舍弃掉了) - * */ - private synchronized Integer replaceConnector(S7Connector oldOne){ - connections.remove(oldOne); - S7Connector connect = connect(host, rack, slot); - if(connect == null){ - return -1; - }else { - connections.add(connect); - return 1; - } - - } - - //虽然是枚举类,但这个是对象锁(不是类锁) - public synchronized S7Connector getConnector() { - int size = connections.size(); - S7Connector s7Connector = connections.get((pickOne + size) % size); - pickOne+=1; - pickOne = (pickOne)%size; - return s7Connector; - } - - - - private synchronized S7Connector connect(String host,Integer rack,Integer slot ){ - try { - S7Connector connector = S7ConnectorFactory - .buildTCPConnector() - .withHost(host) - .withRack(rack) //optional rack 是机架号 - .withSlot(slot) //optional slot 是插槽号 - .build(); - return connector; - }catch (S7Exception e){ -// logger.info("创建S7Connector 连接失败,原因:"+e.getMessage()); - return null; - } - - } - - private void resetConnetctions(){ - this.connections = new ArrayList(); - connectionPool(); - } - - private synchronized void connectionPool(){ - for(int i=0;i { // test.func1();