在java中创建一个单独的线程来读取双向串行端口

在java中创建一个单独的线程来读取双向串行端口,java,multithreading,Java,Multithreading,我想从串行端口读取数据,为此我需要一个单独的线程,该线程将在后台运行,并不断检查“是否可以读取数据”,此外,串行端口是双向的(rx tx)。一种方法是添加一个串行事件监听器,但我不知道如何制作一个后台线程来做同样的事情,请帮助我 我已经创建了一个类read,它从其他类获取一个输入流,我正在创建这个read类的一个线程,以便它在后台运行,查看是否触发了任何receive事件,但是没有发生receive,有什么问题吗 import java.io.IOException; import java.i

我想从串行端口读取数据,为此我需要一个单独的线程,该线程将在后台运行,并不断检查“是否可以读取数据”,此外,串行端口是双向的(rx tx)。一种方法是添加一个串行事件监听器,但我不知道如何制作一个后台线程来做同样的事情,请帮助我

我已经创建了一个类read,它从其他类获取一个输入流,我正在创建这个read类的一个线程,以便它在后台运行,查看是否触发了任何receive事件,但是没有发生receive,有什么问题吗

import java.io.IOException;
import java.io.InputStream; 
import java.util.TooManyListenersException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;


public class read implements SerialPortEventListener, Runnable {

InputStream inputStream;
SerialPort sp;
public read(SerialPort sp, InputStream input){

    inputStream = input;
    this.sp = sp;
    try {
        sp.addEventListener(this);
} catch (TooManyListenersException e) {System.out.println(e);}
    sp.notifyOnDataAvailable(true);
/*    try{
        sp.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
    }
    catch(Exception e){}*/

        new Thread(this).start();

}

@Override
    public void run() {
    try {
        Thread.sleep(20000);
    } catch (InterruptedException e) {System.out.println(e);}
}
@Override
public void serialEvent(SerialPortEvent event) {
    switch(event.getEventType()) {
    case SerialPortEvent.BI:
    case SerialPortEvent.OE:
    case SerialPortEvent.FE:
    case SerialPortEvent.PE:
    case SerialPortEvent.CD:
    case SerialPortEvent.CTS:
    case SerialPortEvent.DSR:
    case SerialPortEvent.RI:
    case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
        break;
    case SerialPortEvent.DATA_AVAILABLE:
        byte[] readBuffer = new byte[1000];

        try {
            while (true) {

                int numBytes;
                if(inputStream.available() > 0){

                    numBytes = inputStream.read(readBuffer);

                }
                else
                    break;

            }
             System.out.print(new String(readBuffer));
             try{
    inputStream.close();
    sp.close();
    }
    catch(Exception e){}
        } catch (IOException e) {System.out.println(e);}
        break;
    }
}
}
我想从串行端口读取数据,为此我需要一个单独的线程,该线程将在后台运行,并不断检查“数据是否可读取”

不,你没有。你需要一个倾听者。你已经有了一个听众。您已将其添加到串行端口。你不需要其他任何东西。您不需要将侦听器作为线程启动。它是JavaComm将自动调用的回调对象

此外,串行端口为双向(rx-tx)。一种方法是添加一个串行事件监听器,但我不知道如何使后台线程也这样做

那是因为你不必这么做。你误解了听众的工作方式。当侦听器激发时,将执行相应回调方法中的代码。就这样。您的部件不需要螺纹

我已经读了一个类,它从其他类获取一个输入流

我正在为这个read类创建一个线程,以便它在后台运行,查看是否触发了任何receive事件

不必要和无意义,见上文

但是收信没有发生,有什么问题吗

import java.io.IOException;
import java.io.InputStream; 
import java.util.TooManyListenersException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;


public class read implements SerialPortEventListener, Runnable {

InputStream inputStream;
SerialPort sp;
public read(SerialPort sp, InputStream input){

    inputStream = input;
    this.sp = sp;
    try {
        sp.addEventListener(this);
} catch (TooManyListenersException e) {System.out.println(e);}
    sp.notifyOnDataAvailable(true);
/*    try{
        sp.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
    }
    catch(Exception e){}*/

        new Thread(this).start();

}

@Override
    public void run() {
    try {
        Thread.sleep(20000);
    } catch (InterruptedException e) {System.out.println(e);}
}
@Override
public void serialEvent(SerialPortEvent event) {
    switch(event.getEventType()) {
    case SerialPortEvent.BI:
    case SerialPortEvent.OE:
    case SerialPortEvent.FE:
    case SerialPortEvent.PE:
    case SerialPortEvent.CD:
    case SerialPortEvent.CTS:
    case SerialPortEvent.DSR:
    case SerialPortEvent.RI:
    case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
        break;
    case SerialPortEvent.DATA_AVAILABLE:
        byte[] readBuffer = new byte[1000];

        try {
            while (true) {

                int numBytes;
                if(inputStream.available() > 0){

                    numBytes = inputStream.read(readBuffer);

                }
                else
                    break;

            }
             System.out.print(new String(readBuffer));
             try{
    inputStream.close();
    sp.close();
    }
    catch(Exception e){}
        } catch (IOException e) {System.out.println(e);}
        break;
    }
}
}
你做错了。删除线程,删除
run()
方法,删除
start()
,然后等待事件传递到回调方法

你的代码是:

case SerialPortEvent.DATA_AVAILABLE:
    byte[] readBuffer = new byte[1000];

    try {
        while (true) {
拆下回路

            int numBytes;
            if(inputStream.available() > 0){
删除测试。这已经是事实,这就是可用数据的含义

                numBytes = inputStream.read(readBuffer);
            }
            else
                break;
删除此
else
break

         System.out.print(new String(readBuffer));
改为

         System.out.print(new String(readBuffer, 0, numBytes));
您忽略了
read()
返回的长度,因此您正在构造一个
字符串
,该字符串在缓冲区的末尾包含超出读取范围的垃圾

         try{
inputStream.close();
sp.close();
}

移除所有这些。您不应该仅仅因为当前没有可读取的数据就关闭输入流。让它开着。目前,在第一条数据到达后,您正在关闭流,从而禁用侦听器。

请分享您的尝试。在这里,我更新了问题,看看您的Runnable什么都没做。事实上,线程将休眠20秒,然后它就死了。