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

 更新时间:2024年05月13日 09:23:40   作者:ZerahMu  
这篇文章主要介绍了Java中串行接口调用优化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

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;
	        }
	        
	 }	


}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringMVC中@RequestMapping注解用法实例

    SpringMVC中@RequestMapping注解用法实例

    通过@RequestMapping注解可以定义不同的处理器映射规则,下面这篇文章主要给大家介绍了关于SpringMVC中@RequestMapping注解用法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • maven利用tomcat插件部署远程Linux服务器的步骤详解

    maven利用tomcat插件部署远程Linux服务器的步骤详解

    Maven已经是Java的项目管理常用方式,下面这篇文章主要给大家介绍了关于maven利用tomcat插件部署远程Linux服务器的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-11-11
  • 图解Spring容器中实例化bean的四种方式

    图解Spring容器中实例化bean的四种方式

    这篇文章主要介绍了图解Spring容器中实例化bean的四种方式,传统应用程序可以通过new和反射方式进行实例化Bean,而Spring IOC容器则需要根据 Bean 定义里的配置元数据,使用反射机制来创建Bean,需要的朋友可以参考下
    2023-11-11
  • gateway基本配置教程

    gateway基本配置教程

    路由(Route)由一个ID,一个目标URI(最终路由到的url地址),一组断言(匹配条件判断)和一组过滤器定义,这篇文章主要介绍了gateway基本配置,需要的朋友可以参考下
    2023-05-05
  • SpringBoot详细讲解通过自定义classloader加密保护class文件

    SpringBoot详细讲解通过自定义classloader加密保护class文件

    这篇文章主要介绍了SpringBoot通过自定义classloader加密class文件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • 在idea中将创建的java web项目部署到Tomcat中的过程图文详解

    在idea中将创建的java web项目部署到Tomcat中的过程图文详解

    这篇文章主要介绍了在idea中将创建的java web项目部署到Tomcat中的过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • 详细介绍Java中的各种锁

    详细介绍Java中的各种锁

    不少同学开始慢慢接触多线时候,对线程之间为了保障数据安全性,一致性有所了解,本文详细解介绍java中的21种锁 ,需要的朋友可以参考下
    2021-06-06
  • java接收ios文件上传的示例代码

    java接收ios文件上传的示例代码

    这篇文章主要为大家详细介绍了java接收ios文件上传的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Java Character类的应用场景

    Java Character类的应用场景

    Java中的Character类提供了处理单个字符的静态方法和实例方法,包括大小写转换、比较、分类等,它在处理用户输入、排序、查找和文本分类等场景中非常有用,下面就来详细的介绍一下如何应用,感兴趣的可以了解一下
    2026-01-01
  • java生成文件夹和文件的简单示例分享

    java生成文件夹和文件的简单示例分享

    这篇文章主要介绍了java生成文件夹和文件的简单示例,需要的朋友可以参考下
    2014-04-04

最新评论