欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Java中串行接口调用优化方式,

来源: javaer 分享于  点击 49873 次 点评:183

Java中串行接口调用优化方式,


目录
  • Java串行接口调用优化
  • Java串口程序的调用
    • RXTX串口插件的使用方法(windows平台)
    • 下面是一些程序运行测试写的方法
  • 总结

    Java串行接口调用优化

    准备面试总结下

     1.CompletableFuture 

     static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(10, 20, 1000L, TimeUnit.MICROSECONDS, new ArrayBlockingQueue<>(100));
     
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            CompletableFuture<Integer> task1 = CompletableFuture.supplyAsync(() -> {
                try {
                    System.out.println("task1");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                return 1000;
            }, poolExecutor);
     
            CompletableFuture<Integer> task2 = CompletableFuture.supplyAsync(() -> {
                try {
                    System.out.println("task2");
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                return 2000;
            }, poolExecutor);
     
     
            CompletableFuture<Integer> task3 = CompletableFuture.supplyAsync(() -> {
                try {
                    System.out.println("task3");
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                return 5000;
            }, poolExecutor);
            Integer result1 = task1.get();
            System.out.println(result1);
            Integer result2 = task2.get();
            System.out.println(result2);
            Integer result3 = task3.get();
            System.out.println(result3);
            CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(task1, task2, task3);
            poolExecutor.shutdown();
            System.out.println("执行完毕");
     
        }

    2.CoutDownLatch 

    static HashMap<String, Integer> map = new HashMap<String, Integer>();
     
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(10, 20, 1000L, TimeUnit.MICROSECONDS, new ArrayBlockingQueue<>(100));
            CountDownLatch countDownLatch = new CountDownLatch(3);
     
     
            Future<Integer> task1 = poolExecutor.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("任务1");
                    Thread.sleep(1000);
                    System.out.println("任务1结束");
                    countDownLatch.countDown();
                    return 1000;
                }
            });
     
            Future<Integer> task2 = poolExecutor.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("任务2");
                    Thread.sleep(500);
                    System.out.println("任务2结束");
                    countDownLatch.countDown();
                    return 500;
                }
            });
     
            Future<Integer> task3 = poolExecutor.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("任务3");
                    Thread.sleep(2000);
                    System.out.println("任务3结束");
                    countDownLatch.countDown();
                    return 2000;
                }
            });
            map.put("task1", task1.get());
            map.put("task2", task1.get());
            map.put("task3", task1.get());
     
     
            System.out.println("线程跑完了");
            countDownLatch.await();
            System.out.println("---------------任务执行结束-------------");
            poolExecutor.shutdown();
     
        }

    3.阻塞获取异步调用结果

       public static void main(String[] args) throws ExecutionException, InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(3);
            Future<String> submit = executorService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Thread.sleep(1000);
                    return "Its done";
                }
            });
            while (true){
                if (submit.isDone()){
                    System.out.println(submit.get());
                    break;
                }
                System.out.println(submit.isDone());
     
            }
        }

    4.除了上面两个方法 还有 CyclicBarrier,Semaphore也都可以实现,可以自己尝试下

    Java串口程序的调用

    RXTX串口插件的使用方法(windows平台)

    1、把rxtxParallel.dll、rxtxSerial.dll拷贝到:C:\WINDOWS\system32下。

    2、如果是在开发的时候(JDK),需要把RXTXcomm.jar、rxtxParallel.dll、rxtxSerial.dll拷贝到…\jre…\lib\ext下;如:D:\Program Files\Java\jre1.6.0_02\lib\ext

    3、需要选中项目右键->Preperties->Java Build Path->Libraries->选择External Folder–>选择RXTXcomm.jar.

    • 拷贝 RXTXcomm.jar 到 <JAVA_HOME>\jre\lib\ext目录中;
    • 拷贝 rxtxSerial.dll 到 <JAVA_HOME>\jre\bin目录中;
    • 拷贝 rxtxParallel.dll 到 <JAVA_HOME>\jre\bin目录中;

    其中<JAVA_HOME>为jdk安装路径

    下面是一些程序运行测试写的方法

    package com.serialport;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Date;
    import java.util.Enumeration;
    import java.util.HashSet;
    import java.util.TooManyListenersException;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    
    import com.readtable.HexTest;
    
    import gnu.io.CommPort;
    import gnu.io.CommPortIdentifier;
    import gnu.io.PortInUseException;
    import gnu.io.SerialPort;
    import gnu.io.SerialPortEvent;
    import gnu.io.SerialPortEventListener;
    import gnu.io.UnsupportedCommOperationException;
    
    /**
     * 这个是一个更加完善的串口调用及接收函数类
     * @author Administrator
     *
     */
    public class SerialReceiver extends Thread implements SerialPortEventListener{
      HexTest hexT2 = new HexTest();
      
      
      	 
      static CommPortIdentifier portId; // 串口通信管理类
      static Enumeration<?> portList; // 有效连接上的端口的枚举
      static InputStream inputStream; //从串口来数据的输入流
      static OutputStream outputStream;// 向串口输出的流
      static SerialPort serialPort; // 串口的引用
      
      private static byte[] readBuffer = new byte[1024]; // 4k的buffer空间,缓存串口读入的数据 
      int numBytes;  //buffer中的实际数据字节数 ,每一次读取的字节数据 
      // 堵塞队列用来存放读到的数据
      private BlockingQueue<String> msgQueue = new LinkedBlockingQueue<String>();
    
     
      //其他的常量设置
      //端口是否打开了  
      boolean isOpen = false;  
      // 端口读入数据事件触发后,等待n毫秒后再读取,以便让数据一次性读完  
      public static int PARAMS_DELAY = 1000; // 延时等待端口数据准备的时间  
      public static int PARAMS_TIMEOUT = 2000; // 超时时间  
      public static String PARAMS_PORT = "COM4"; // 端口名称  
      public static int PARAMS_RATE = 2400; // 波特率  
      public static int PARAMS_DATABITS = 8; // 数据位  
      public static int PARAMS_STOPBITS = 1; // 停止位  
      public static int PARAMS_PARITY = 1; // 奇偶校验  
      
    
      /**
       * SerialPort EventListene 的方法,持续监听端口上是否有数据流
       */
    	@Override
    	public void serialEvent(SerialPortEvent event) {
    		// TODO Auto-generated method stub
    		switch (event.getEventType()) {
            case SerialPortEvent.DATA_AVAILABLE:// 当有可用数据时读取数据
        	  receTest();     
              break;
          }
    	}
    	
    	/**
    	 * 接收的数据进行打印测试
    	 */
    	private void receTest() {
    
    	    try {
                  numBytes = 0;
                  while (inputStream.available() > 0) {            	 
                      numBytes += inputStream.read(readBuffer,numBytes,1024);
                  }
    
                    if (numBytes > 0) {
                        msgQueue.add(new Date() +"方法2接收的字节数为:"+numBytes+ "   收到的数据为:-----"
                        		+ hexT2.arrayToHexStr(readBuffer, 0, numBytes));
                        readBuffer = new byte[1024];  //重新构造缓冲对象,否则有可能会影响接下来接收的数据
                    } else {
                        msgQueue.add("额------没有读到数据");
                    }
                
            } catch (IOException e) {
            	
            }
    	
    	}
    	
    	
    	
    	/**
    	 * 根据串口名,获取串口接口
    	 * @param portName
    	 * @return
    	 */
    	public SerialPort OpenSerialPort(String portName) {
    		 //获取设备上的所有端口
    	      portList = CommPortIdentifier.getPortIdentifiers();
    
    	      while (portList.hasMoreElements()) {
    	          // 获取相应串口对象
    	          portId = (CommPortIdentifier) portList.nextElement();
    	          
    	          System.out.println("设备类型:--->" + portId.getPortType());
    	          System.out.println("设备名称:--->" + portId.getName());
    	          
    	          //判断端口类型是否为串口
    	          if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
    
    	              // 判断如果输入的串口名对应的串口存在,就打开该串口
    	              if (portId.getName().equals(portName)) {
    	                  try {
    	                      // 打开串口名字为COM_4(名字任意),延迟为2毫秒
    	                      serialPort = (SerialPort) portId.open("COM_3", 2000);
                              return serialPort;
    	                  } catch (PortInUseException e) {
    	                      e.printStackTrace();
    	                      return null;
    	                  }
    	                  
    	              }
    	          
    	          }
    	       }
    	      return null;
    	      
    	}
    	
    	/**
    	 * 打开串口的函数
    	 * @param portName  串口名
    	 * @param bitrate   波特率
    	 * @param databit   数据位
    	 * @param stopbit   停止位
    	 * @param parity    校验方式:奇 偶 无
    	 * @return
    	 */
    	public int OpenComport(String portName,int bitrate,int databit,int stopbit,int parity) {
    		serialPort = OpenSerialPort(portName);
    		if(serialPort != null) {
    			// 设置当前串口的输入输出流
                try {
                    inputStream = serialPort.getInputStream();
                    outputStream = serialPort.getOutputStream();
                } catch (IOException e) {
                    e.printStackTrace();
                    return 0;
                }
                // 给当前串口添加一个监听器
                try {
                    serialPort.addEventListener(this);
                } catch (TooManyListenersException e) {
                    e.printStackTrace();
                    return 0;
                }
                // 设置监听器生效,即:当有数据时通知
                serialPort.notifyOnDataAvailable(true);
                
                //给串口设置一些参数
                try {
                    // 比特率、数据位、停止位、奇偶校验位
                    serialPort.setSerialPortParams( bitrate,databit,stopbit,parity);
                } catch (UnsupportedCommOperationException e) {
                    e.printStackTrace();
                    return 0;
                }
    
                return 1;
    		}
    		
    		return 0;
    	}
    	
    
    	
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		 try {
    	            System.out.println("--------------任务处理线程运行了--------------");
    	            while (true) {
    	                //如果堵塞队列中存在数据就将其输出
    	                if (msgQueue.size() > 0) {
    	                    System.out.println(msgQueue.take());
    	                }
    	            }
    	        } catch (InterruptedException e) {
    	            // TODO Auto-generated catch block
    	            e.printStackTrace();
    	        }
    	}
    	
    	 public static void main(String[] args) {
    		 
    		    SerialReceiver cRead = new SerialReceiver();
    		    
    		    PARAMS_PORT = "COM3"; // 端口名称  
    		    PARAMS_RATE = 2400; // 波特率  
    		    PARAMS_DATABITS = SerialPort.DATABITS_8;  //数据位
    		    PARAMS_STOPBITS = SerialPort.STOPBITS_1; // 停止位             
    		    PARAMS_PARITY =  SerialPort.PARITY_EVEN; // 奇偶校验
    		    
    	        int i = cRead.OpenComport(PARAMS_PORT,PARAMS_RATE,PARAMS_DATABITS,
    	        		                  PARAMS_STOPBITS,PARAMS_PARITY);
    	        if (i == 1) {
    	            // 启动线程来处理收到的数据
    	        	 cRead.start();
    	            try {
    	            	
    	            	//发送指令
    	            	HexTest hexT = new HexTest();
    	        		byte[] bst = hexT.ReadTable07(1,1, 0,3);
    	            	outputStream.write(bst, 0,bst.length);
    
    	            } catch (IOException e) {
    	                // TODO Auto-generated catch block
    	                e.printStackTrace();
    	            }
    	        } else {
    	            return;
    	        }
    	        
    	 }	
    
    
    }
    
    

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持3672js教程。

    您可能感兴趣的文章:
    • java远程调用接口、URL的方式代码
    • Java使用Soap方式调用WebService接口代码示例
    • java后端调用第三方接口返回图片流给前端的具体代码实现
    • JAVA重复调用接口导致数据不一致的问题解决
    • Java如何远程调用对方接口
    相关栏目:

    用户点评