异步传递来自一些 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 负责在队列中有字节“供获取”时执行处理代码。如果队列为空,则线程正在休息。
我想用 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 负责在队列中有字节“供获取”时执行处理代码。如果队列为空,则线程正在休息。