这是我的第一篇帖子,所以请放心吧:)。我正在重构一些连接代码以使用非阻塞IO,并在调用byteButter.put(byte[])或byteBuffer.put(byte[]、索引、长度)时遇到一个空点异常。异常发生在这一行中。
localBuffer.put(sendLengthBuffer,0,sendLengthBuffer.length);
奇怪的是,null指针仅在我第一次调用该方法时发生,所有后续的写入尝试都按预期的方式运行。
代码:
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)*编辑*结果,空指针是在分配byteBuffer.compact()后立即调用byteBuffer()的结果。仍然不清楚为什么会在这个场景中在put()上抛出空指针,但我似乎已经找到了解决方案。谢谢你的评论!
发布于 2016-01-20 15:24:16
本地缓冲区似乎是在另一个线程中创建的,但是本地缓冲区的字段并不是线程安全的,因此您不会立即看到它们。
我建议使用ThreadLocal直接字节缓冲区。直接字节缓冲区比堆缓冲区更有效,因为它不需要对本机内存进行额外的复制。
https://stackoverflow.com/questions/34902972
复制相似问题