Java中串行接口調用優(yōu)化方式
Java串行接口調用優(yōu)化
準備面試總結下
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("任務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("---------------任務執(zhí)行結束-------------");
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也都可以實現(xiàn),可以自己嘗試下
Java串口程序的調用
RXTX串口插件的使用方法(windows平臺)
1、把rxtxParallel.dll、rxtxSerial.dll拷貝到:C:\WINDOWS\system32下。
2、如果是在開發(fā)的時候(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;
/**
* 這個是一個更加完善的串口調用及接收函數(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ù)據(jù)字節(jié)數(shù) ,每一次讀取的字節(jié)數(shù)據(jù)
// 堵塞隊列用來存放讀到的數(shù)據(jù)
private BlockingQueue<String> msgQueue = new LinkedBlockingQueue<String>();
//其他的常量設置
//端口是否打開了
boolean isOpen = false;
// 端口讀入數(shù)據(jù)事件觸發(fā)后,等待n毫秒后再讀取,以便讓數(shù)據(jù)一次性讀完
public static int PARAMS_DELAY = 1000; // 延時等待端口數(shù)據(jù)準備的時間
public static int PARAMS_TIMEOUT = 2000; // 超時時間
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; // 奇偶校驗
/**
* 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:// 當有可用數(shù)據(jù)時讀取數(shù)據(jù)
receTest();
break;
}
}
/**
* 接收的數(shù)據(jù)進行打印測試
*/
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]; //重新構造緩沖對象,否則有可能會影響接下來接收的數(shù)據(jù)
} else {
msgQueue.add("額------沒有讀到數(shù)據(jù)");
}
} catch (IOException e) {
}
}
/**
* 根據(jù)串口名,獲取串口接口
* @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;
}
/**
* 打開串口的函數(shù)
* @param portName 串口名
* @param bitrate 波特率
* @param databit 數(shù)據(jù)位
* @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;
}
// 給當前串口添加一個監(jiān)聽器
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
e.printStackTrace();
return 0;
}
// 設置監(jiān)聽器生效,即:當有數(shù)據(jù)時通知
serialPort.notifyOnDataAvailable(true);
//給串口設置一些參數(shù)
try {
// 比特率、數(shù)據(jù)位、停止位、奇偶校驗位
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) {
//如果堵塞隊列中存在數(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; // 奇偶校驗
int i = cRead.OpenComport(PARAMS_PORT,PARAMS_RATE,PARAMS_DATABITS,
PARAMS_STOPBITS,PARAMS_PARITY);
if (i == 1) {
// 啟動線程來處理收到的數(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;
}
}
}
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringMVC中@RequestMapping注解用法實例
通過@RequestMapping注解可以定義不同的處理器映射規(guī)則,下面這篇文章主要給大家介紹了關于SpringMVC中@RequestMapping注解用法的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-06-06
maven利用tomcat插件部署遠程Linux服務器的步驟詳解
Maven已經(jīng)是Java的項目管理常用方式,下面這篇文章主要給大家介紹了關于maven利用tomcat插件部署遠程Linux服務器的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧。2017-11-11
SpringBoot詳細講解通過自定義classloader加密保護class文件
這篇文章主要介紹了SpringBoot通過自定義classloader加密class文件,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04
在idea中將創(chuàng)建的java web項目部署到Tomcat中的過程圖文詳解
這篇文章主要介紹了在idea中將創(chuàng)建的java web項目部署到Tomcat中的過程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04

