为什么我的缓冲区在此代码中返回null?

时间:2013-04-01 19:20:47

标签: java object concurrency locking nullpointerexception

代码改编自http://rxtx.qbang.org/wiki/index.php/Event_Based_Two_Way_Communication

我正在尝试使用SerialReader类读取公共缓冲区,并通过SerialWriter类通过Serial发送该缓冲区,但是每次调用Writer时缓冲区都显示为null。使用TwoWaySerialCommTest的连接方法初始化代码(粘贴在下面以供参考)

public SerialWriter ( OutputStream out )
            {
                this.out = out;
            }

            public SerialWriter ( OutputStream out, byte[] buffer)
            {
                    this.out = out;
                    this.buffer = buffer;
            }

            public void run ()
            {
                    while(true)
                    {
                            lock.lock();
                            try
                        {
                            dataAvailable.await();
                            System.out.println("Waking up");
                            int i = 0;
                            if (this.buffer != null)
                            {
                                    System.out.println("Buffer isn't empty");
                                    while(buffer[i] != ((byte)'\n') && i < buffer.length - 1)
                                    {
                                            this.out.write(buffer[i]);
                                    }
                            }
                            else
                            {
                                    System.out.println("Buffer is null");
                                    System.out.println(this.buffer.toString());
                            }
                        }
                        catch ( IOException e )
                        {
                            e.printStackTrace();
                            System.exit(-1);
                        }
                        catch(Exception e)
                        {
                            e.printStackTrace();
                        }

                            finally
                            {
                                    lock.unlock();
                            }
                    }
            }
        }

Serial Reader class

public static class SerialReader implements SerialPortEventListener
        {
            private InputStream in;
            byte[] buffer;

            public SerialReader ( InputStream in )
            {
                this.in = in;
            }

            public SerialReader (InputStream in, byte[] buffer)
            {
                    this.in = in;
                    this.buffer = buffer;
            }

            public void serialEvent(SerialPortEvent arg0) {
                lock.lock();
                    int data;
                    if (buffer != null)
                    {
                     for(int i = 0; i < buffer.length; i++)
                    {
                            if (buffer[i] != 0)
                            {
                                    System.out.print((char)buffer[i]);
                            }
                    }
                    }
                    buffer = new byte[1024];

                try
                {
                    int len = 0;
                    while ( ( data = in.read()) > -1 )
                    {
                        if ( data == '\n' ) {
                            break;
                        }
                        buffer[len++] = (byte) data;
                    }
                    System.out.println(new String(buffer,0,len));
                    for(int i = 0; i < buffer.length; i++)
                    {
                            if (buffer[i] != 0)
                            {
                                    System.out.print((char)buffer[i]);
                            }
                    }
                    System.out.println();
                    dataAvailable.signal();
                }
                catch ( IOException e )
                {
                    e.printStackTrace();
                    System.exit(-1);
                }
                finally
                {
                    lock.unlock();
                }
            }

        }

TwoWaySerialCommTest(截断)

    import gnu.io.SerialPortEvent;
    import gnu.io.SerialPortEventListener;

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.concurrent.locks.*;

    /**
     * This version of the TwoWaySerialComm example makes use of the
     * SerialPortEventListener to avoid polling.
     *
     */
    public class TwoWaySerialCommTest
    {
            static Lock lock = new ReentrantLock();
            static Condition dataAvailable = lock.newCondition();
            public volatile byte[] buffer;

            public TwoWaySerialCommTest()
        {
            super();
        }


        void connect ( String portName ) throws Exception
        {
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
            if ( portIdentifier.isCurrentlyOwned() )
            {
                System.out.println("Error: Port is currently in use");
            }
            else
            {
                CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);

                if ( commPort instanceof SerialPort )
                {
                    SerialPort serialPort = (SerialPort) commPort;
                    serialPort.setSerialPortParams(57600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);

                    InputStream in = serialPort.getInputStream();
                    OutputStream out = serialPort.getOutputStream();

                    (new Thread(new SerialWriter(out , buffer))).start();

                    serialPort.addEventListener(new SerialReader(in , buffer));
                    serialPort.notifyOnDataAvailable(true);

                }
                else
                {
                    System.out.println("Error: Only serial ports are handled by this example.");
                }
            }
        }

1 个答案:

答案 0 :(得分:1)

这一行似乎有一个问题:

buffer = new byte[1024];

我不认为您希望将本地buffer分配给那里的新字节数组。这会导致编写器写入自己的数组,并且传入的数据由读者共享。分配buffer只会影响编写器内的局部变量。

另外,什么阻止输入流覆盖buffer?如果行长度大于1024,那么您将获得一个超出范围的数组异常。

最后,您没有将\n字符写入buffer。因此,读者将在输出中打印许多\0个空字符。