Java中串行接口調(diào)用優(yōu)化方式
Java串行接口調(diào)用優(yōu)化
準(zhǔn)備面試總結(jié)下
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("執(zhí)行完畢");
}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("任務(wù)1");
Thread.sleep(1000);
System.out.println("任務(wù)1結(jié)束");
countDownLatch.countDown();
return 1000;
}
});
Future<Integer> task2 = poolExecutor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println("任務(wù)2");
Thread.sleep(500);
System.out.println("任務(wù)2結(jié)束");
countDownLatch.countDown();
return 500;
}
});
Future<Integer> task3 = poolExecutor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println("任務(wù)3");
Thread.sleep(2000);
System.out.println("任務(wù)3結(jié)束");
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("---------------任務(wù)執(zhí)行結(jié)束-------------");
poolExecutor.shutdown();
}3.阻塞獲取異步調(diào)用結(jié)果
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.除了上面兩個(gè)方法 還有 CyclicBarrier,Semaphore也都可以實(shí)現(xiàn),可以自己嘗試下
Java串口程序的調(diào)用
RXTX串口插件的使用方法(windows平臺(tái))
1、把rxtxParallel.dll、rxtxSerial.dll拷貝到:C:\WINDOWS\system32下。
2、如果是在開發(fā)的時(shí)候(JDK),需要把RXTXcomm.jar、rxtxParallel.dll、rxtxSerial.dll拷貝到…\jre…\lib\ext下;如:D:\Program Files\Java\jre1.6.0_02\lib\ext
3、需要選中項(xiàng)目右鍵->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安裝路徑
下面是一些程序運(yùn)行測試寫的方法
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;
/**
* 這個(gè)是一個(gè)更加完善的串口調(diào)用及接收函數(shù)類
* @author Administrator
*
*/
public class SerialReceiver extends Thread implements SerialPortEventListener{
HexTest hexT2 = new HexTest();
static CommPortIdentifier portId; // 串口通信管理類
static Enumeration<?> portList; // 有效連接上的端口的枚舉
static InputStream inputStream; //從串口來數(shù)據(jù)的輸入流
static OutputStream outputStream;// 向串口輸出的流
static SerialPort serialPort; // 串口的引用
private static byte[] readBuffer = new byte[1024]; // 4k的buffer空間,緩存串口讀入的數(shù)據(jù)
int numBytes; //buffer中的實(shí)際數(shù)據(jù)字節(jié)數(shù) ,每一次讀取的字節(jié)數(shù)據(jù)
// 堵塞隊(duì)列用來存放讀到的數(shù)據(jù)
private BlockingQueue<String> msgQueue = new LinkedBlockingQueue<String>();
//其他的常量設(shè)置
//端口是否打開了
boolean isOpen = false;
// 端口讀入數(shù)據(jù)事件觸發(fā)后,等待n毫秒后再讀取,以便讓數(shù)據(jù)一次性讀完
public static int PARAMS_DELAY = 1000; // 延時(shí)等待端口數(shù)據(jù)準(zhǔn)備的時(shí)間
public static int PARAMS_TIMEOUT = 2000; // 超時(shí)時(shí)間
public static String PARAMS_PORT = "COM4"; // 端口名稱
public static int PARAMS_RATE = 2400; // 波特率
public static int PARAMS_DATABITS = 8; // 數(shù)據(jù)位
public static int PARAMS_STOPBITS = 1; // 停止位
public static int PARAMS_PARITY = 1; // 奇偶校驗(yàn)
/**
* SerialPort EventListene 的方法,持續(xù)監(jiān)聽端口上是否有數(shù)據(jù)流
*/
@Override
public void serialEvent(SerialPortEvent event) {
// TODO Auto-generated method stub
switch (event.getEventType()) {
case SerialPortEvent.DATA_AVAILABLE:// 當(dāng)有可用數(shù)據(jù)時(shí)讀取數(shù)據(jù)
receTest();
break;
}
}
/**
* 接收的數(shù)據(jù)進(jìn)行打印測試
*/
private void receTest() {
try {
numBytes = 0;
while (inputStream.available() > 0) {
numBytes += inputStream.read(readBuffer,numBytes,1024);
}
if (numBytes > 0) {
msgQueue.add(new Date() +"方法2接收的字節(jié)數(shù)為:"+numBytes+ " 收到的數(shù)據(jù)為:-----"
+ hexT2.arrayToHexStr(readBuffer, 0, numBytes));
readBuffer = new byte[1024]; //重新構(gòu)造緩沖對(duì)象,否則有可能會(huì)影響接下來接收的數(shù)據(jù)
} else {
msgQueue.add("額------沒有讀到數(shù)據(jù)");
}
} catch (IOException e) {
}
}
/**
* 根據(jù)串口名,獲取串口接口
* @param portName
* @return
*/
public SerialPort OpenSerialPort(String portName) {
//獲取設(shè)備上的所有端口
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
// 獲取相應(yīng)串口對(duì)象
portId = (CommPortIdentifier) portList.nextElement();
System.out.println("設(shè)備類型:--->" + portId.getPortType());
System.out.println("設(shè)備名稱:--->" + portId.getName());
//判斷端口類型是否為串口
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
// 判斷如果輸入的串口名對(duì)應(yīng)的串口存在,就打開該串口
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;
}
/**
* 打開串口的函數(shù)
* @param portName 串口名
* @param bitrate 波特率
* @param databit 數(shù)據(jù)位
* @param stopbit 停止位
* @param parity 校驗(yàn)方式:奇 偶 無
* @return
*/
public int OpenComport(String portName,int bitrate,int databit,int stopbit,int parity) {
serialPort = OpenSerialPort(portName);
if(serialPort != null) {
// 設(shè)置當(dāng)前串口的輸入輸出流
try {
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
return 0;
}
// 給當(dāng)前串口添加一個(gè)監(jiān)聽器
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
e.printStackTrace();
return 0;
}
// 設(shè)置監(jiān)聽器生效,即:當(dāng)有數(shù)據(jù)時(shí)通知
serialPort.notifyOnDataAvailable(true);
//給串口設(shè)置一些參數(shù)
try {
// 比特率、數(shù)據(jù)位、停止位、奇偶校驗(yàn)位
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("--------------任務(wù)處理線程運(yùn)行了--------------");
while (true) {
//如果堵塞隊(duì)列中存在數(shù)據(jù)就將其輸出
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; //數(shù)據(jù)位
PARAMS_STOPBITS = SerialPort.STOPBITS_1; // 停止位
PARAMS_PARITY = SerialPort.PARITY_EVEN; // 奇偶校驗(yàn)
int i = cRead.OpenComport(PARAMS_PORT,PARAMS_RATE,PARAMS_DATABITS,
PARAMS_STOPBITS,PARAMS_PARITY);
if (i == 1) {
// 啟動(dòng)線程來處理收到的數(shù)據(jù)
cRead.start();
try {
//發(fā)送指令
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;
}
}
}
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot實(shí)現(xiàn)自動(dòng)發(fā)送郵件
這篇文章主要為大家詳細(xì)介紹了Spring Boot實(shí)現(xiàn)自動(dòng)發(fā)送郵件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
SpringBoot項(xiàng)目導(dǎo)入aliyun oss starter依賴后啟動(dòng)報(bào)錯(cuò)問題
這篇文章主要介紹了SpringBoot項(xiàng)目導(dǎo)入aliyun oss starter依賴后啟動(dòng)報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
Spring Boot中使用Redis做緩存的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于Spring Boot中使用Redis做緩存的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-06-06

