當前位置:首頁 » 編程語言 » java非阻塞

java非阻塞

發布時間: 2022-11-05 06:57:31

java如何實現非阻塞的io

這個IO不用等待對方返回結果,
打開IO指令執行完成後,
會繼續執行指令後面的操作,
當對方返回數據後會出發一個事件,
告訴你數據回來了,
例如使用selector的非阻塞IO.你應當看看java.nio.

㈡ java NIO的非阻塞問題!

OIO是讀寫阻塞, NIO是讀寫非阻塞,就是說伺服器等待客戶端連接這塊都是阻塞的, 一旦建立連接了, OIO下, 我讀取客戶端發來的信息會因網路延時問題又一次阻塞, 你發消息時也是一樣 而NIO下, 你的selector.select()如果注冊了read或者write, 當消息到達服務端時, 人家從阻塞中醒來提醒你,換句話說, 不是說阻塞消失了, 而是你想多處阻塞等待還是一處阻塞, 然後你干別的事, 數據來了通知你. 如果有興趣你還可以了解下AIO, 一樣有阻塞, 不過很多事操作系統幫你歸口做了而已, 與NIO的區別就是, NIO是數據到了提醒你讀, AIO是數據讀成功了提醒你一切都好. 總之, 這三種java都可支持, 都存在阻塞, 總的區別就是你在這件事上擔當的角色不同

㈢ java同非同步請求和阻塞非阻塞的區別

1、關於非同步:

java中非同步請求就是*調用*在發出之後,這個調用就直接返回了,所以沒有返回結果。換句話說,當一個非同步過程調用發出後,調用者不會立刻得到結果。而是在*調用*發出後,*被調用者*通過狀態、通知來通知調用者,或通過回調函數處理這個調用。

2、阻塞式I/O模型:默認情況下,所有套接字都是阻塞的。

一個輸入操作通常包括兩個不同階段:

(1)等待數據准備好;
(2)從內核向進程復制數據。

㈣ java socket 阻塞和非阻塞 會對數據傳輸有什麼影響

阻塞 阻塞調用是指調用結果返回之前,當前線程會被掛起。函數只有在得到結果之後才會返回。有人也許會把阻塞調用和同步調用等同起來,實際上他是不同的。對於同步調用來說,很多時候當前線程還是激活的,只是從邏輯上當前函數沒有返回而已。例如,我們在CSocket中調用Receive函數,如果緩沖區中沒有數據,這個函數就會一直等待,直到有數據才返回。而此時,當前線程還會繼續處理各種各樣的消息。如果主窗口和調用函數在同一個線程中,除非你在特殊的界面操作函數中調用,其實主界面還是應該可以刷新。socket接收數據的另外一個函數recv則是一個阻塞調用的例子。當socket工作在阻塞模式的時候,如果沒有數據的情況下調用該函數,則當前線程就會被掛起,直到有數據為止。 非阻塞 非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回。 對象的阻塞模式和阻塞函數調用 對象是否處於阻塞模式和函數是不是阻塞調用有很強的相關性,但是並不是一一對應的。阻塞對象上可以有非阻塞的調用方式,我們可以通過一定的API去輪詢狀態,在適當的時候調用阻塞函數,就可以避免阻塞。而對於非阻塞對象,調用特殊的函數也可以進入阻塞調用。函數select就是這樣的一個例子

㈤ java什麼是阻塞隊列 非阻塞隊列

阻塞隊列與普通隊列的區別在於,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來,如從隊列中移除一個或者多個元素,或者完全清空隊列.
從5.0開始,JDK在java.util.concurrent包里提供了阻塞隊列的官方實現。盡管JDK中已經包含了阻塞隊列的官方實現,但是熟悉其背後的原理還是很有幫助的。一下是阻塞隊列的實現:
public class BlockingQueue {

private List queue = new LinkedList();

private int limit = 10;

public BlockingQueue(int limit){

this.limit = limit;

}

public synchronized void enqueue(Object item)

throws InterruptedException {

while(this.queue.size() == this.limit) {

wait();

}

if(this.queue.size() == 0) {

notifyAll();

}

this.queue.add(item);

}

public synchronized Object dequeue()

throws InterruptedException{

while(this.queue.size() == 0){

wait();

}

if(this.queue.size() == this.limit){

notifyAll();

}

return this.queue.remove(0);

}

}
http://..com/link?url=sfWg_--pIZTP9i9plB7AvEDTUgG3m

㈥ java 中 阻塞隊列 非阻塞隊列 和普通隊列的區別是什麼

阻塞隊列與普通隊列的區別在於,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來,如從隊列中移除一個或者多個元素,或者完全清空隊列.

從5.0開始,JDK在java.util.concurrent包里提供了阻塞隊列的官方實現。盡管JDK中已經包含了阻塞隊列的官方實現,但是熟悉其背後的原理還是很有幫助的。一下是阻塞隊列的實現:

publicclassBlockingQueue{

privateListqueue=newLinkedList();

privateintlimit=10;

publicBlockingQueue(intlimit){

this.limit=limit;

}

publicsynchronizedvoidenqueue(Objectitem)

throwsInterruptedException{

while(this.queue.size()==this.limit){

wait();

}

if(this.queue.size()==0){

notifyAll();

}

this.queue.add(item);

}

()

throwsInterruptedException{

while(this.queue.size()==0){

wait();

}

if(this.queue.size()==this.limit){

notifyAll();

}

returnthis.queue.remove(0);

}

}

㈦ Java NIO怎麼理解通道和非阻塞

nio引入了buffer、channel、selector等概念。
通道相當於之前的I/O流。
「通道」太抽象了。java解釋不清的東西只能看它底層是怎麼解釋的——操作系統的I/O控制,通道控制方式?
I/O設備:CPU——通道——設備控制器——I/O設備
(通道和設備控制器的關系是多對多,設備控制器和I/O設備的關系也是多對多。)
I/O過程,參考http://www.nbrkb.net/lwt/jsjsj/asm/INTR&DMA.htm:
1.CPU在執行用戶程序時遇到I/O請求,根據用戶的I/O請求生成通道程序(也可以是事先編好的)。放到內存中,並把該通道程序首地址放入CAW中。
2.CPU執行「啟動I/O」指令,啟動通道工作。
3.通道接收「啟動I/O」指令信號,從CAW(記錄下一條通道指令存放的地址)中取出通道程序首地址,並根據此地址取出通道程序的第一條指令,放入CCW(記錄正在執行的通道指令)中;同時向CPU發回答信號,通知「啟動I/O」指令完成完畢,CPU可繼續執行。
4.與此同時,通道開始執行通道程序,進行物理I/O操作。當執行完一條指令後,如果還有下一條指令則繼續執行;否則表示傳輸完成,同時自行停止,通知CPU轉去處理通道結束事件,並從CCW中得到有關通道狀態。

如此一來,主處理器只要發出一個I/O操作命令,剩下的工作完全由通道負責。I/O操作結束後,I/O通道會發出一個中斷請求,表示相應操作已完成。

通道控制方式是對數據塊進行處理的,並非位元組。

通道控制方式就是非同步I/O,參考http://blog.csdn.net/historyasamirror/article/details/5778378:
I/O分兩段:1.數據從I/O設備到內核緩沖區。2.數據從內核緩沖區到應用緩沖區

I/O類型:
1.非同步I/O不會產生阻塞,程序不會等待I/O完成,繼續執行代碼,等I/O完成了再執行一個什麼回調函數,代碼執行效率高。很容易聯想到ajax。這個一般用於I/O操作不影響之後的代碼執行。
2.阻塞I/O,程序發起I/O操作後,進程阻塞,CPU轉而執行其他進程,I/O的兩個步驟完成後,向CPU發送中斷信號,進程就緒,等待執行。
3.非阻塞I/O並非都不阻塞,其實是第一步不阻塞,第二部阻塞。程序發起I/O操作後,進程一直檢查第一步是否完成,CPU一直在循環詢問,完成後,進程阻塞直到完成第二步。明白了!這個是「站著茅坑不拉屎」,CPU利用率最低的。邏輯和操作系統的程序直接控制方式一樣。
阻塞不阻塞描述的是發生I/O時當前線程的狀態。
以上是操作系統的I/O,那麼java的nio又是怎樣的呢?
個人覺得是模仿了通道控制方式。
先看看nio的示例代碼:
服務端TestReadServer.java

import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class TestReadServer { /*標識數字*/ private int flag = 0; /*緩沖區大小*/ private int BLOCK = 1024*1024*10; /*接受數據緩沖區*/ private ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK); /*發送數據緩沖區*/ private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK); private Selector selector; public TestReadServer(int port) throws IOException { // 打開伺服器套接字通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 伺服器配置為非阻塞 serverSocketChannel.configureBlocking(false); // 檢索與此通道關聯的伺服器套接字 ServerSocket serverSocket = serverSocketChannel.socket(); // 進行服務的綁定 serverSocket.bind(new InetSocketAddress(port)); // 通過open()方法找到Selector selector = Selector.open(); // 注冊到selector,等待連接 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("Server Start----"+port+":"); } // 監聽 private void listen() throws IOException { while (true) { // 選擇一組鍵,並且相應的通道已經打開 selector.select(); // 返回此選擇器的已選擇鍵集。 Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); iterator.remove(); handleKey(selectionKey); } } } // 處理請求 private void handleKey(SelectionKey selectionKey) throws IOException { // 接受請求 ServerSocketChannel server = null; SocketChannel client = null; String receiveText; String sendText; int count=0; // 測試此鍵的通道是否已准備好接受新的套接字連接。 if (selectionKey.isAcceptable()) { // 返回為之創建此鍵的通道。 server = (ServerSocketChannel) selectionKey.channel(); // 接受到此通道套接字的連接。 // 此方法返回的套接字通道(如果有)將處於阻塞模式。 client = server.accept(); // 配置為非阻塞 client.configureBlocking(false); // 注冊到selector,等待連接 client.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { // 返回為之創建此鍵的通道。 client = (SocketChannel) selectionKey.channel(); //將緩沖區清空以備下次讀取 receivebuffer.clear(); //讀取伺服器發送來的數據到緩沖區中 System.out.println(System.currentTimeMillis()); count = client.read(receivebuffer); System.out.println(System.currentTimeMillis() + "~"+count); } } /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub int port = 1234; TestReadServer server = new TestReadServer(port); server.listen(); } }客戶端TestReadClient.javaimport java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class TestReadClient { /*標識數字*/ private static int flag = 0; /*緩沖區大小*/ private static int BLOCK = 1024*1024*10; /*接受數據緩沖區*/ private static ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK); /*發送數據緩沖區*/ private static ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK); /*伺服器端地址*/ private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress( "localhost", 1234); public static void main(String[] args) throws IOException { // TODO Auto-generated method stub // 打開socket通道 SocketChannel socketChannel = SocketChannel.open(); // 設置為非阻塞方式 socketChannel.configureBlocking(false); // 打開選擇器 Selector selector = Selector.open(); // 注冊連接服務端socket動作 socketChannel.register(selector, SelectionKey.OP_CONNECT); // 連接 socketChannel.connect(SERVER_ADDRESS); // 分配緩沖區大小內存 Set<SelectionKey> selectionKeys; Iterator<SelectionKey> iterator; SelectionKey selectionKey; SocketChannel client; String receiveText; String sendText; int count=0; while (true) { //選擇一組鍵,其相應的通道已為 I/O 操作準備就緒。 //此方法執行處於阻塞模式的選擇操作。 selector.select(); //返回此選擇器的已選擇鍵集。 selectionKeys = selector.selectedKeys(); //System.out.println(selectionKeys.size()); iterator = selectionKeys.iterator(); while (iterator.hasNext()) { selectionKey = iterator.next(); if (selectionKey.isConnectable()) { System.out.println("client connect"); client = (SocketChannel) selectionKey.channel(); // 判斷此通道上是否正在進行連接操作。 // 完成套接字通道的連接過程。 if (client.isConnectionPending()) { client.finishConnect(); System.out.println("完成連接!"); sendbuffer.clear(); BufferedInputStream br = new BufferedInputStream(new FileInputStream(new File("D:\BigData.zip"))); byte[] b = new byte[BLOCK]; br.read(b); sendbuffer.put(b); sendbuffer.flip(); System.out.println(System.currentTimeMillis()); client.write(sendbuffer); System.out.println(System.currentTimeMillis()); } client.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { client = (SocketChannel) selectionKey.channel(); //將緩沖區清空以備下次讀取 receivebuffer.clear(); //讀取伺服器發送來的數據到緩沖區中 count=client.read(receivebuffer); if(count>0){ receiveText = new String( receivebuffer.array(),0,count); System.out.println("客戶端接受伺服器端數據--:"+receiveText); client.register(selector, SelectionKey.OP_WRITE); } } } selectionKeys.clear(); } } }例子是TestReadClient向TestReadServer發送一個本地文件。TestReadServer收到後每次列印讀取到的位元組數。

如何體現非同步I/O?
看看TestReadClient中的:

if (selectionKey.isConnectable()) { System.out.println("client connect"); client = (SocketChannel) selectionKey.channel(); // 判斷此通道上是否正在進行連接操作。 // 完成套接字通道的連接過程。 if (client.isConnectionPending()) { client.finishConnect();如果沒有client.finishConnect();這句等待完成socket連接,可能會報異常:java.nio.channels.NotYetConnectedException

非同步的才不會管你有沒有連接成功,都會執行下面的代碼。這里需要人為的干預。
如果要證明是java的nio單獨使用非阻塞I/O,真沒辦法!!!阻塞非阻塞要查看進程。。。
不過還有種說法,叫非同步非阻塞。上面那段,是用非同步方式創建連接,進程當然沒有被阻塞。使用了finishConnect()這是人為將程序中止,等待連接創建完成(是模仿阻塞將當前進程阻塞掉,還是模仿非阻塞不斷輪詢訪問,不重要了反正是程序卡住沒往下執行)。
所以,創建連接的過程用非同步非阻塞I/O可以解釋的通。那read/write的過程呢?
根據上面例子的列印結果,可以知道這個過程是同步的,沒執行完是不會執行下面的代碼的。至於底下是使用阻塞I/O還是非阻塞I/O,對於應用級程序來說不重要了。
阻塞還是非阻塞,對於正常的開發(創立連接,從連接中讀寫數據)並沒有多少的提升,操作過程都類似。
那NIO憑什麼成為高性能架構的基礎,比起IO,性能優越在哪裡,接著猜。。。
java nio有意模仿操作系統的通道控制方式,那他的底層是不是就是直接使用操作系統的通道?
通道中的數據是以塊為單位的,之前的流是以位元組為單位的,同樣的數據流操作外設的次數較多。代碼中channel都是針對ByteBuffer對象進行read/write的,而ByteBuffer又是ByteBuffer.allocate(BLOCK);這樣創建的,是一個連續的塊空間。
那ByteBuffer是不是也是模擬操作系統的緩存
緩存在io也有,如BufferedInputStream。CPU和外設的速度差很多,緩存為了提高CPU使用率,等外設將數據讀入緩存後,CPU再統一操作,不用外設讀一次,CPU操作一次,CPU的效率會被拉下來。。。

㈧ Java:什麼叫做同步非阻塞IO呢

這個IO不用等待對方返回結果,打開IO指令執行完成後,會繼續執行指令後面的操作,當對方返回數據後會出發一個事件,告訴你數據回來了,例如使用selector的非阻塞IO.你應當看看java.nio.

㈨ java 中實現非阻塞通信需要哪些類和介面的支持

因為這個必須帶一個埠參數,例如8080之類的。 應該編譯好之後,在命令行下面調用,或者設置eclipse的運行設置,配置成運行時帶參數,並自己填上一個埠號。

非阻塞演算法屬於並發演算法,可以安全地派生它們的線程,不通過鎖定派生,而是通過低級的原子性的硬體原生形式;

例如比較和交換。非阻塞演算法的設計與實現極為困難,但是它們能夠提供更好的吞吐率,對生存問題(例如死鎖和優先順序反轉)也能提供更好的防禦。使用底層的原子化機器指令取代鎖,比如比較並交換(CAS,compare-and-swap)。

(9)java非阻塞擴展閱讀:

非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回。但是非阻塞I/O的問題是:由於完整的I/O沒有完成,立即返回的並不是業務層期望的數據,而僅僅是當前調用的狀態。為了獲取完整的數據,應用程序需要重復調用I/O操作來確認是否完成。這種重復調用判斷操作是否完成的技術叫做輪詢。調用之後立即返回。

㈩ JAVA 非阻塞通信(NIO)相比普通socket通信,非阻塞表現在哪裡本質區別是什麼

0,重連,重新再來過一次唄。
1,NIO 本身是提供非阻塞式的網路訪問,使用 selector 來輪詢事件,因此用 selector 才能改進性能,一個 selector 可以用在多個 socket 通信中而不像以前傳統的一個線程一個 socket 流這么麻煩地管理它們。
2,客戶端與服務端是互不影響的,完全不相關。我們完全不需要關心對方是C++ / VB 還是 Java ,只要雙方使用的都是 TCP 協議就行了。

NIO 是在與操作系統的模塊打交道,盡量提高性能,所有的真實過程其實都是在 JVM 的 native 代碼與操作系統中處理了,對我們應用程序來說,使用什麼方法並沒有區別。

熱點內容
雲列印伺服器硬體 發布:2025-01-11 07:44:56 瀏覽:768
怎麼在手機上更改wifi密碼 發布:2025-01-11 07:37:26 瀏覽:336
開機啟動serviceandroid 發布:2025-01-11 07:35:24 瀏覽:523
天龍八部腳本設置自動喊話 發布:2025-01-11 07:31:37 瀏覽:310
硒標准溶液配置為什麼要加鹽酸 發布:2025-01-11 07:27:51 瀏覽:253
怎麼做電腦編程 發布:2025-01-11 07:14:36 瀏覽:481
壓縮圓環 發布:2025-01-11 06:41:37 瀏覽:512
安卓背面是什麼字母 發布:2025-01-11 06:37:55 瀏覽:215
個人小程序怎麼購買雲伺服器 發布:2025-01-11 06:33:08 瀏覽:912
手機mc怎麼玩伺服器國際服 發布:2025-01-11 06:18:33 瀏覽:160