异步传递来自一些 Java 类 之间的串行通信的数据列表

Passing a List of data from serial communication between some Java classes asynchronously

我想用 JSerialComm 和 JavaFX 开发一个应用程序。我在JSeialComm中使用async delimiter-mode数据接收方式:

class MessageListener implements SerialPortMessageListener {

    private List<Byte> list;

    public List<Byte> getList() {
        return list;
    }

    public MessageListener() {
        list = new ArrayList<Byte>();

    }

    public void addToList(Byte number) {
        list.add(number);
    }
    
    public void flushList()
    {
        list.clear();
    }

    @Override
    public int getListeningEvents() {
        return SerialPort.LISTENING_EVENT_DATA_RECEIVED;
    }

    @Override
    public byte[] getMessageDelimiter() {
        return new byte[] { (byte) 0x0D, (byte) 0x0A };
    }

    @Override
    public boolean delimiterIndicatesEndOfMessage() {
        return true;
    }

    @Override
    public void serialEvent(SerialPortEvent event) {
        byte[] delimitedMessage = event.getReceivedData();

        for (byte b : delimitedMessage) {
            addToList(b);
        }

    }
}

总体功能还可以。我在 Main class 中打开端口并将数据发送到串行接收器。 (实际上,Main class 本身在这里并不重要,但可以在下面的 link 中找到。)

由于数据接收是异步进行的,数据在MessageListenerclass中接收,并暂时存储在list变量中。我正在寻找一种方法来通知 Main class 有关任何新数据的信息,以便它可以更新 GUI 并在这些数据上做一些业务。可能会不断轮询新数据,但效率不高。

整个项目都可以访问here

看看LinkedBlockingDeque or any other class that implements BlockingQueue。他们有一个 take() 方法阻塞,直到队列有可用的元素。当元素可用时,take() 方法解除阻塞,并允许执行处理代码。

我在等待串行数据时做了类似的事情,因为我想将其排队等待处理并按顺序处理。

在您的侦听器中 class 您可以将元素放入队列中:

class MessageListener implements SerialPortMessageListener {

    private LinkedBlockingDeque list;

    public LinkedBlockingDeque getList() {
        return list;
    }

    public MessageListener() {
        list = new LinkedBlockingDeque();

    }

    public void addToList(Byte number) {
        list.put(number);
    }
...

然后创建一个线程,传入您的父级 StackPane 或您需要更改的任何 GUI 对象以及对队列的引用和 运行 一个等待队列中有字节的循环。如果您不关心它是否被阻塞,您也可以从主 class 执行此操作,但我通常会尽可能避免阻塞 main()

public class QueueProcessor extends Thread
{
    LinkedBlockingDeque queue = null;
    StackPane root = null;
    public QueueProcessor(StackPane tmpRoot, LinkedBlockingDeque tmpQueue)
    {
        root = tmpRoot;
        queue = tmpQueue;
    }
    public void run()
    {
        while (true)
        {
            //this will block until the queue has elements
            Byte b = (Byte)(queue.take());
            //processing code here
        }
    }
}

当您从队列中取出时,实际上是从队列中移除对象(即不需要 clear() 方法)。 Java 负责在队列中有字节“供获取”时执行处理代码。如果队列为空,则线程正在休息。