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;
}
}
}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

