Java NIO ByteBuffer.put空指针异常

时间:2016-01-20 14:38:29

标签: java nullpointerexception nio bytebuffer

这是我的第一篇文章,所以对我很轻松:)。我正在努力重构一些连接代码以使用非阻塞IO,并在调用byteButter.put(byte [])或byteBuffer.put(byte [],index,length)时遇到空点异常。例外情况发生在这一行

  

localBuffer.put(sendLengthBuffer,0,sendLengthBuffer.length);

奇怪的是空指针只在第一次调用方法时出现,所有后续的写入尝试都按预期运行。

代码:

public void write(SocketChannel sc,PayloadLength pl,ArrayBlockingQueue<byte[]> queue) throws IOException{
        while(!queue.isEmpty()){
            byte[] message = queue.poll();
            if(message != null && message.length > 0){
                if(bufferHasRemaining()){
                    SystemLogger.getLogger().logMe(LoggerLevel.INFO, this.getClass().getSimpleName(), "writer compacting");
                    localBuffer.compact();
                }else{
                    SystemLogger.getLogger().logMe(LoggerLevel.INFO, this.getClass().getSimpleName(), "writer compacting");
                    localBuffer.clear();
                }
                //calculate the message length
                byte[] sendLengthBuffer = new byte[pl.getLengthSize()];
                pl.parseWriteLength(sendLengthBuffer, message.length);
                localBuffer.put(sendLengthBuffer,0,sendLengthBuffer.length);
                localBuffer.put(message,0,message.length);
                localBuffer.flip();

//              //write until buffer is empty
//              //TODO: potential infinite loop here
//              while(localBuffer.hasRemaining()){
//                  sc.write(localBuffer);
//              }
                sc.write(localBuffer);
                if(bufferHasRemaining()){
                    //could not write all bytes to channel, most likely the sockets write buffer is full
                    break;
                }

            }
        }

这是堆栈跟踪:

EXCEPTION: null - null
STACK TRACE:
java.nio.HeapByteBuffer.put(HeapByteBuffer.java:189)
com.discover.paymentservices.commons.net.nio.NIOWriteHandler.write(NIOWriteHandler.java:57)
com.discover.paymentservices.tibco.channel.nio.BaseNIOConnectionHandler.run(BaseNIOConnectionHandler.java:603)

**** ***** EDIT 事实证明空指针是在分配byteBuffer后立即调用byteBuffer.compact()的结果。仍然不确定为什么在这种情况下null指针被抛出put()但我似乎找到了解决方案。感谢您的评论!

1 个答案:

答案 0 :(得分:0)

看来本地缓冲区正在另一个线程中创建,但是本地缓冲区的字段不是线程安全的,因此您不会立即看到它们。

我建议使用ThreadLocal直接字节缓冲区。直接字节缓冲区比堆缓冲区更有效,因为它不需要额外的副本到本机内存。