2016-04-27 20 views
0

java doc表示在执行写入操作时,会发生以前未完成的操作。如何解决java7 nio套接字WritePendingException?

当试图写一个 异步socket通道和先前的写抛出未经检查的异常还没有完成。

一个简单的代码来描述这个阶段:

sendMsg(data: ByteBuffer): Future[Unit] = { 
    val p = Promise[Unit] 
    this.synchronized { 
     //socketChannel: AsynchronousSocketChannel is connected socket 
     socketChannel.write(data, 1, new CompletionHandler[Integer, Int] { 
     override def completed(result: Integer, attachment: Int): Unit = { 
      p.trySuccess(Unit) 
     } 

     override def failed(exc: Throwable, attachment: Int): Unit = { 
      p.tryFailure(exc) 
     } 
     } 
    } 
    p.future 
    } 

我试图锁定write操作,直到其与此unwork代码完成:

val writeLock = new ReentrantLock 

def sendMsg(data: ByteBuffer) = { 
    val p = Promise[Unit] 

    writeLock.lock() 

    socketChannel.write(data, 1, new CompletionHandler[Integer, Int] { 
    override def completed(result: Integer, attachment: Int): Unit = { 
     writeLock.unlock() 

     p.trySuccess(Unit) 
    } 

    override def failed(exc: Throwable, attachment: Int): Unit = { 
     p.tryFailure(exc) 
     writeLock.unlock() 
    } 
    }) 
    p.future 
} 

但它抛出IllegalMonitorStateException例外。
希望一些帮助来同时运行它。 此外,我还有一个问题,为什么不是java sdk处理它。似乎我应该等待异步操作complete.Thanks

回答

0

是不是Java应该处理这个问题,因为如果你会失去对你的控制权码。

您不必“等待”。你写你的数据,并“写作”使客户端无效。当写入完成(这就是为什么你有这种方法),你重新验证客户端的写作。

关键概念是,在选择要写入的通道时,可以跳过那些在该通道上“无效”的通道。

我几年前做了一个NIO的异步IO实现,您不妨来看看,以获得进一步的提示

https://github.com/NadirRoGue/asyncnetworkengine/tree/master/src/org/mmocore/network

采取在 MMOClient.sendPacket() WriteHandler.completed()

+0

看看特别是在'MMOConnection.startWriteTask '在线程池中使用'write'方法的地方。但在'MMOConnection.executeWriteTask'处调用的只锁定当前线程的方法围绕'startWriteTask'方法。如何确保'write'处于挂起状态时'executeWriteTask'不能执行? – LoranceChen

+0

@LoranceChen这就是为什么我有'_pendingWrite'标志,以避免挂起时执行它。另一种方法是使用'completed'方法触发下一次写入,而'sendQueue'则有数据包。一旦这个是空的,写任务将停止被触发,所以你将不得不使用'sendPacket'(带有另一个标志,它最后是相同的)来触发写任务 – Nadir

+0

,你能举个例子吗?使用lib?我认为'_pendingWrite'完全没有影响,因为'_core.executeWriteTask'会立即返回。 – LoranceChen

相关问题