日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java NIO总结

發布時間:2023/12/3 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java NIO总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、NIO

NIO是new IO,也是非阻塞IO。有Channel、Selector、Buffer、Pipe、FileLock等類。

Buffer在java.nio包

Channel、Selector、Pipe、FileLock等在java.nio.channels包

?

二、Channel通道

設置非阻塞configureBlocking(false);

注冊選擇器register(selector,SelectionKey.OP_XXX)

使用方法read(Buffer) ,write(Buffer)

使用方法open()獲取Channel

  • FileChannel ? ? ? 使用FileInputStream,FileOutputStream,RandomAccessFile或者open(Path path, OpenOption... options)可以獲取channel對象
  • ServerSocketChannel
  • SocketChannel
  • DatagramChannel
  • Pipe.SinkChannel ? ? ? ? 使用pipe.sink()
  • Pipe.SourceChannel ? ?使用pipe.source()

?

三、Buffer緩沖

除了boolean類型沒有Buffer類,其他七種基本數據類型都有Buffer緩沖。而byte有兩個Buffer緩沖,一個是在堆,一個在文件的內存映射區.

方法clear() ?清空Buffer

方法compact()移動Buffer數據到起始位置,設置為position在數據末尾

方法flip() 反轉Buffer,將寫模式轉成讀模式

方法rewind() 從0開始讀數據

方法hasRemaining()判斷是否還有剩余數據

ByteBuffer

ShortBuffer

IntBuffer

LongBuffer

FloatBuffer

DoubleBuffer

CharBuffer

MappedByteBuffer ? ? ? ?通過FileChannel.map方法產生

?

四、Selector 選擇器

Selector selector = Selector.open(); channel.configureBlocking(false); SelectionKey key = channel.register(selector,Selectionkey.OP_READ);

select方法

int select() int select(long timeout) int selectNow()

select()阻塞到至少有一個通道在你注冊的事件上就緒了。

select(long timeout)和select()一樣,除了最長會阻塞timeout毫秒(參數)。

selectNow()不會阻塞,不管什么通道就緒都立刻返回

?

調用Selector.wakeup()方法,阻塞在select()方法上的線程會立馬返回。

用完Selector后調用其close()方法會關閉該Selector,且使注冊到該Selector上的所有SelectionKey實例無效。通道本身并不會關閉。

?

五、SelectionKey

Selector四種事件用SelectionKey的四個常量來表示:

SelectionKey.OP_CONNECT

SelectionKey.OP_ACCEPT

SelectionKey.OP_READ

SelectionKey.OP_WRITE

?

在Selector的select方法返回不為0時,獲取SelectionKey

Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator keyIterator = selectedKeys.iterator(); while(keyIterator.hasNext()) {
SelectionKey key
= keyIterator.next();if(key.isAcceptable()) {// a connection was accepted by a ServerSocketChannel.} else if (key.isConnectable()) {// a connection was established with a remote server.} else if (key.isReadable()) {// a channel is ready for reading} else if (key.isWritable()) {// a channel is ready for writing}keyIterator.remove(); //必須移除掉,否則下一次channel還留在selectionkeySet中。 }

?

六、Pipe 管道

?(1)SinkChannel

Pipe pipe = Pipe.open(); Pipe.SinkChannel sinkChannel = pipe.sink(); String data = "a sink pipe channel"; ByteBuffer buf = ByteBuffer.allocate(50); buf.clear(); buf.put(data.getBytes()); buf.flip();while(buf.hasRemaining()) {sinkChannel.write(buf); }

?

(2)SourceChannel

Pipe.SourceChannel sourceChannel = pipe.source(); ByteBuffer buf = ByteBuffer.allocate(50); int length = sourceChannel.read(buf);

?

?七、FileLock

FileLock與Lock接口相似,但沒有實現Lock接口

(1)概念

  • 共享鎖: 共享讀操作,但只能一個寫(讀可以同時,但寫不能)
  • 獨占鎖: 只有一個讀或一個寫(讀和寫都不能同時)

(2)FileLock FileChannel.lock(long position, long size, boolean shared)

shared的含義:是否使用共享鎖,一些不支持共享鎖的操作系統,將自動將共享鎖改成排它鎖。可以通過調用isShared()方法來檢測獲得的是什么類型的鎖。

(3) lock()和tryLock()的區別:

lock()阻塞的方法,鎖定范圍可以隨著文件的增大而增加。無參lock()默認為獨占鎖;有參lock(0L, Long.MAX_VALUE, true)為共享鎖。

tryLock()非阻塞,當未獲得鎖時,返回null.

(4)FileLock的生命周期:在調用FileLock.release(),或者Channel.close(),或者JVM關閉

(5)FileLock是線程安全的

(6)同一進程內,在文件鎖沒有被釋放之前,不可以再次獲取。即在release()方法調用前,只能lock()或者tryLock()一次。

FileChannel channel = null;FileLock lock=null;try {RandomAccessFile raf = new RandomAccessFile("data.txt", "rw");channel = raf.getChannel();//獲得鎖方法一:lock(),阻塞的方法,當文件鎖不可用時,當前進程會被掛起 lock = channel.lock();//無參lock()為獨占鎖 //lock = channel.lock(0L, Long.MAX_VALUE, true);//有參lock()為共享鎖,有寫操作會報異常 //獲得鎖方法二:trylock(),非阻塞的方法,當文件鎖不可用時,tryLock()會得到null值 //do { // lock = channel.tryLock(); //} while (null == lock); } catch (Exception e) {}finally{if (lock!=null) {lock.release();}if (channel!=null) {channel.close();}}

?

?八、ServerSocketChannel 服務器通道

package cn.edu.scau.mk;import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel;/**** @author MK*/ public class Test {volatile static boolean isFinished = false;public static void main(String[] args) throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(888));while (!isFinished) {SocketChannel socketChannel = serverSocketChannel.accept();//1.阻塞模式//線程處理socketChannel...//2.非阻塞模式if (socketChannel != null) {//處理socketChannel... }}serverSocketChannel.close();} }

?

九、SocketChannel TCP通道

package cn.edu.scau.mk;import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel;/**** @author MK*/ public class Test {volatile static boolean isFinished = false;public static void main(String[] args) throws IOException {SocketChannel socketChannel = SocketChannel.open();socketChannel.configureBlocking(false);//設置為非阻塞socketChannel.connect(new InetSocketAddress("https://www.baidu.com", 80));String data = "a socket channel connect";ByteBuffer buf = ByteBuffer.allocate(48);buf.clear();buf.put(data.getBytes());buf.flip();while (!socketChannel.finishConnect()) {//等待連接成功或者做其他的事 }//非阻塞狀態有可能沒有寫入數據就返回了while (buf.hasRemaining()) {socketChannel.write(buf);}socketChannel.close();} }

?

十、DatagramChannel UDP通道

package cn.edu.scau.mk;import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SocketChannel;/**** @author MK*/ public class Test {volatile static boolean isFinished = false;public static void main(String[] args) throws IOException {DatagramChannel channel = DatagramChannel.open();channel.socket().bind(new InetSocketAddress(888));//channel.connect(new InetSocketAddress("www.baidu.com", 80));ByteBuffer buf = ByteBuffer.allocate(48);buf.clear();//接收SocketAddress sa=channel.receive(buf);//connect通道可以使用read//int bytesRead = channel.read(buf); buf.clear();buf.put("datagram channel".getBytes());buf.flip();//發送int length = channel.send(buf, new InetSocketAddress("www.baidu.com", 80));//connect通道可以使用write//channel.write(buf); channel.close();} }

?

總結

以上是生活随笔為你收集整理的Java NIO总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。