2012-11-13 85 views
0

根據這篇文章: https://stackoverflow.com/questions/6666659/threading-implications-of-asynchronousbytechannel異步套接字通道的java實現並不保證完成處理程序在單獨的線程中被調用。所以如果你正在讀入一個字節緩衝區,你怎麼在wait()之後調用notify()?java異步套接字通道/完成處理程序

 class CH implements CompletionHandler<Integer,Integer> 
     {    
      public volatile int i = 0; 
      public void completed(Integer i, Integer o) 
      { 
       this.i = i; 
       synchronized(this) 
       { 
        this.notify(); 
      } 
      } 

     public void failed(Throwable t, Integer o) 
     { 
      this.i = -5;     
      synchronized(this) 
      { 
       this.notify(); 
      } 
     } 

    } 

       CH x = new CH(); 
       synchronized (x) {    
        while (!(x.i == -1 || x.i == -5)) { 
          aschannel.read(bytebuffer, 5, TimeUnit.SECONDS, null, x); 
          x.wait();           
          if(x.i != -1 && x.i != -5){ 
            bytebuffer.flip(); 
            filechannel.write(bytebuffer.array,0,x.i); 
            bytebuffer.clear(); 
           } 
       }  


       } 

回答

2

你的程序可能會工作,因爲wait()釋放監視程序,並允許回調執行。

但是,異步I/O的整個想法是將I/O交換啓動器從等待(並保持線程)中解放出來。如果你想等待,那麼只需使用好的舊同步API。或者在沒有CompletionHandler的情況下調用read,並返回Future,然後等待Future。

+0

同步I/O非常麻煩,並且在與緩慢的服務器連接時出現停頓,即使讀取超時也是如此。異步未來方法不會拋出被超時異常中斷,並且有時會在讀取操作中停頓。只有完成處理程序方法會中斷。 –

+1

如果你真的想使用'CompletionHandler',看看我的庫df4j-nio2(https://github.com/rfqu/df4j的一部分)。它使用Actor風格的Nio2。 –