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ù)據的輸入流 static OutputStream outputStream;// 向串口輸出的流 static SerialPort serialPort; // 串口的引用 private static byte[] readBuffer = new byte[1024]; // 4k的buffer空間,緩存串口讀入的數(shù)據 int numBytes; //buffer中的實際數(shù)據字節(jié)數(shù) ,每一次讀取的字節(jié)數(shù)據 // 堵塞隊列用來存放讀到的數(shù)據 private BlockingQueue<String> msgQueue = new LinkedBlockingQueue<String>(); //其他的常量設置 //端口是否打開了 boolean isOpen = false; // 端口讀入數(shù)據事件觸發(fā)后,等待n毫秒后再讀取,以便讓數(shù)據一次性讀完 public static int PARAMS_DELAY = 1000; // 延時等待端口數(shù)據準備的時間 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ù)據位 public static int PARAMS_STOPBITS = 1; // 停止位 public static int PARAMS_PARITY = 1; // 奇偶校驗 /** * SerialPort EventListene 的方法,持續(xù)監(jiān)聽端口上是否有數(shù)據流 */ @Override public void serialEvent(SerialPortEvent event) { // TODO Auto-generated method stub switch (event.getEventType()) { case SerialPortEvent.DATA_AVAILABLE:// 當有可用數(shù)據時讀取數(shù)據 receTest(); break; } } /** * 接收的數(shù)據進行打印測試 */ 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ù)據為:-----" + hexT2.arrayToHexStr(readBuffer, 0, numBytes)); readBuffer = new byte[1024]; //重新構造緩沖對象,否則有可能會影響接下來接收的數(shù)據 } else { msgQueue.add("額------沒有讀到數(shù)據"); } } 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; } /** * 打開串口的函數(shù) * @param portName 串口名 * @param bitrate 波特率 * @param databit 數(shù)據位 * @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ù)據時通知 serialPort.notifyOnDataAvailable(true); //給串口設置一些參數(shù) try { // 比特率、數(shù)據位、停止位、奇偶校驗位 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ù)據就將其輸出 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ù)據位 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ù)據 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; } } }
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringBoot項目導入aliyun oss starter依賴后啟動報錯問題
這篇文章主要介紹了SpringBoot項目導入aliyun oss starter依賴后啟動報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01