linugb118--java space

          Java

          Java NIO---Channel部分

          Java NIO---Channel部分

          Channel 是連接buffer和Io設備之間的管道,當然channel也可以一頭連接channel

          Basic Channel Interface:
          public interface Channel
          {
          public boolean isOpen( );
          public void close( ) throws IOException;
          }

          1.open channel
          channel作為i/o 設備的管道,分為兩種,一種文件(file),另一種是端口(Socket)
          file相關的只有fileChannel
          socket相關的有SocketChannel, ServerSocketChannel和DatagramChannel.

          socket channel可以通過factory創建新的socket channel
          比如
          SocketChannel sc = SocketChannel.open( );
          sc.connect (new InetSocketAddress ("somehost", someport));

          ServerSocketChannel ssc = ServerSocketChannel.open( );
          ssc.socket( ).bind (new InetSocketAddress (somelocalport));

          而fileChannel 則不能這樣,他是在一個打開的andomAccessFile, FileInputStream或者FileOutputStream
          對象上getChannel()
          比如
          RandomAccessFile raf = new RandomAccessFile ("somefile", "r");
          FileChannel fc = raf.getChannel( );

          2.Using Channels
          三個接口:
          public interface ReadableByteChannel
          extends Channel
          {
          public int read (ByteBuffer dst) throws IOException;
          }
          public interface WritableByteChannel
          extends Channel
          {
          public int write (ByteBuffer src) throws IOException;
          }
          public interface ByteChannel
          extends ReadableByteChannel, WritableByteChannel
          {
          }

          需要注意的是 fileChannel 雖然也有write,read方法,但是他們能否調用write read方法是由file相關的訪問權限決定的。

          channel 有blocking和nonblocking兩種模式,nonblocking是指永遠不會將一個正在調用的線程sleep,他們被請求的結果要么
          立刻完成,要么返回一個nothing的結果。
          只有stream-oriented的channels(比如sockets and pipes)可以用nonblocking模式

          3.Closing Channels
          和buffer不一樣,channel不能被重用,用完之后一定要close,此外當一個線程被設置為interrupt狀態,當該線程試圖訪問某個channel
          的話,該channel將立刻關閉。


          4.Scatter/Gather
          當我們在多個buffer上執行一個i/O操作的時候,我們需要將多個buffer放在一個buffer數組一并讓channel來處理
          Scatter/Gather interface:

          public interface ScatteringByteChannel
          extends ReadableByteChannel
          {
          public long read (ByteBuffer [] dsts)
          throws IOException;
          public long read (ByteBuffer [] dsts, int offset, int length)
          throws IOException;
          }
          public interface GatheringByteChannel
          extends WritableByteChannel
          {
          public long write(ByteBuffer[] srcs)
          throws IOException;
          public long write(ByteBuffer[] srcs, int offset, int length)
          throws IOException;
          }

          例子:
          ByteBuffer header = ByteBuffer.allocateDirect (10);
          ByteBuffer body = ByteBuffer.allocateDirect (80);
          ByteBuffer [] buffers = { header, body };
          int bytesRead = channel.read (buffers);

          5.File Channels
          filechannel 只能是blocking模式也就是被鎖住模式,不能是nonblocking模式
          public abstract class FileChannel
          extends AbstractChannel
          implements ByteChannel, GatheringByteChannel, ScatteringByteChannel
          {
          // This is a partial API listing
          public abstract void truncate (long size)
          public abstract void force (boolean metaData)
          }
          fileChannel 中有truncate和force 兩個方法
          truncate (long size)是以給定的size來切斷file
          force (boolean metaData) file屬性的修改立刻影響到disk上

          6.File Locking
          file 鎖雖然在fileChannel中提出,但是需要注意本身lock是和file相關,而且不同的操作系統提供的file也有不同,和channel無關的

          public abstract class FileChannel
          extends AbstractChannel
          implements ByteChannel, GatheringByteChannel, ScatteringByteChannel
          {
          // This is a partial API listing
          public final FileLock lock( )
          public abstract FileLock lock (long position, long size,
          boolean shared)
          public final FileLock tryLock( )
          public abstract FileLock tryLock (long position, long size,
          boolean shared)
          }

          lock 有三個參數,第一個是開始鎖住的file的postion, 第二個是鎖住的file大小,前面這兩個參數就能定義了一塊lock范圍,第三個是
          顯示lock是shared(true)類型還是exclusive(false)類型,
          沒有參數的lock()其實等同于fileChannel.lock (0L, Long.MAX_VALUE, false);
          FileLock 本身是線程安全的,可以多個線程同時訪問

          tryLock() 和Lock()相似,當某個lock因為其他原因不能被獲取,那么就要用tryLock() 這個時候就返回null
          FileLock總關聯一個特定的channel,可以通過channel()獲取相關聯的channel,當FileLock release(),那么對于的channel也就相應的close();

          7.Memory-Mapped Files
          Memory-mapped files 一般效率更高,而且因為他是和操作系統相關的,所有他不會消費jvm分配的內存
          通過map()來建立MappedByteBuffer,
          mapped buffers和lock有點不同,lock和產生它的channel綁定,如果channel closed那么lock也就消失
          而mapped buffers本身也沒有ummap方法,他是通過自身不再被引用然后被系統垃圾回收的。

          8.Channel-to-Channel Transfers
          channel直接的傳輸可以提供更好的效率

          public abstract class FileChannel
          extends AbstractChannel
          implements ByteChannel, GatheringByteChannel, ScatteringByteChannel
          {
          // This is a partial API listing
          public abstract long transferTo (long position, long count,
          WritableByteChannel target)
          Java NIO
          90
          public abstract long transferFrom (ReadableByteChannel src,
          long position, long count)
          }

          這個是能在filechannel之間使用,兩個socketchannel之間不能直接使用transferTo和transferFrom,但是因為socketchannel繼承WritableByteChannel and ReadableByteChannel,所有可以將一個文件的內容transferTo socketChannel或直接通過transferFrom從socketChannel中讀取數據

          9.Socket Channels
          對應以前一般一個線程對應一個socket,而在NIO中可以一個線程對應成百上千的socket,同時沒有性能降低的問題
          三種socket channel(DatagramChannel,SocketChannel, and ServerSocketChannel)
          DatagramChannel和SocketChannel 有read和write的方法
          而ServerSocketChannel 則是監聽connection和創建SocketChannel,他本身不參與數據的傳輸
          這三個channel都可以通過socket()方法獲取到對應的Socket,ServerSocket,DatagramSocket
          需要說明的是,socket不一樣要綁定channel,通過傳統的new 創建socket,那么getChannel()就會返回null

          SocketChannel 有Nonblocking和blocking 兩種模式
          SocketChannel sc = SocketChannel.open( );
          sc.configureBlocking (false); // nonblocking
          ...
          if ( ! sc.isBlocking( )) {
          doSomething (cs);
          }
          可以通過configureBlocking 來設置,true表示blocking mode 而false 表示nonblocking mode
          對應大型應用并發處理的 建議使用nonblocking mode
          看看下面的例子:
          Socket socket = null;
          Object lockObj = serverChannel.blockingLock( );
          // have a handle to the lock object, but haven't locked it yet
          // may block here until lock is acquired
          synchronize (lockObj)
          {
          // This thread now owns the lock; mode can't be changed
          boolean prevState = serverChannel.isBlocking( );
          serverChannel.configureBlocking (false);
          socket = serverChannel.accept( );
          serverChannel.configureBlocking (prevState);
          }
          // lock is now released, mode is allowed to change
          if (socket != null) {
          doSomethingWithTheSocket (socket);
          }
          體驗一下 blockingLock()和lock()的區別

          SocketChannel 可以通過finishConnect( ),isConnectPending( ), or isConnected( )獲取當前connection的狀態

          socket是面向流的,datagram是面向packet的
          因此DatagramChannel 就是面向packet協議的channel,比如UDP/IP

          10.pipe 方式 可以研究一下

           

           

           

           


           

          posted on 2010-09-10 15:54 linugb118 閱讀(3350) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          My Links

          Blog Stats

          常用鏈接

          留言簿(1)

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 安龙县| 浦江县| 伊吾县| 盐池县| 吉首市| 张家界市| 南华县| 阳东县| 安多县| 富宁县| 岗巴县| 克拉玛依市| 兴安县| 襄城县| 唐山市| 康定县| 章丘市| 交城县| 枣阳市| 衡水市| 京山县| 墨脱县| 章丘市| 庆阳市| 井冈山市| 神木县| 白城市| 济阳县| 四会市| 桐梓县| 镇巴县| 娱乐| 辉南县| 乐清市| 崇明县| 江陵县| 尤溪县| 常德市| 将乐县| 余干县| 藁城市|