这是我的第一篇文章,所以对我很轻松:)。我正在努力重构一些连接代码以使用非阻塞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()但我似乎找到了解决方案。感谢您的评论!
答案 0 :(得分:0)
看来本地缓冲区正在另一个线程中创建,但是本地缓冲区的字段不是线程安全的,因此您不会立即看到它们。
我建议使用ThreadLocal
直接字节缓冲区。直接字节缓冲区比堆缓冲区更有效,因为它不需要额外的副本到本机内存。