处理具有高频读取的两个线程

时间:2013-12-30 14:49:34

标签: java multithreading concurrency serial-port real-time

我正在编写一个简单的应用程序,不断通过蓝牙从串口读取一些数据,然后在2个图表上绘制这些数据。我想出了将数据缓冲到字节缓冲区然后从代码的其他部分读取它的想法。问题是我必须非常频繁地读取数据(一次只读取5个字节)并且我在线程同步方面存在一些问题。串口读取部分不允许打印线程在大多数时间读取任何内容。有时它会通过并打印一些数据。这两个是使用buffer作为锁定对象的唯一线程。

我想我可能会错过一些基本的同步原则,但是我开始没有想法如何解决这个问题。

从串口部分读取:

public void startReading() {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            resetBuffer();
            read = true;
            try {
                serialPort.purgePort(SerialPort.PURGE_RXCLEAR);
                byte[] buf = new byte[5];
                int bytes;

                while (read) {
                    synchronized (buffer) {
                        try {
                            bytes = inputStream.blockingRead(buf);
                            System.out.println(buf);

                            System.arraycopy(buf, 0, buffer, bufferPos, bytes);
                            bufferPos += buf.length;

                            buffer.notifyAll();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }

            } catch (SerialPortException e) {
                e.printStackTrace();
            }
        }
    });
    thread.start();

}

打印数据部分(循环中):

 synchronized (buffer) {
        while (serialPortConnection.getBufferLength() < 5) {
            try {
                buffer.wait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    readBytesToStringBuffer();
    printLineIfAvailable();

1 个答案:

答案 0 :(得分:1)

while (read) {
  synchronized (buffer) {
    try {
       bytes = inputStream.blockingRead(buf);

你的问题不在于经常阅读;它在阻止中。您在buffer上获取监视器,然后输入阻止I / O调用。你花了很少的时间在那个电话之外,因此在synchronized区之外。

建议:

首先从synchronized之外的端口读取,然后获取监视器以将数据传输到共享结构。