Ⅰ java io read不能結束,一直堵塞在for循環裡面,怎麼解決
ava io read不能結束,派段和一直堵塞在for循環里塵盯面,解決辦法
不要用燃局for循環 ,改成while循環
讀取完畢關閉for循序break
Ⅱ JAVA怎麼中斷IO阻塞的線程
1、寫程序的關鍵是要有控制流,當程序塊中的處理涉及到死循環的時候更要加量的控制。
2、像這種情況,兩個步驟,
一,為IO時的創建線程,加一個數量的閾值,超過它後則不再創建。
二,為每個線程設置標志變數標志該線程是否已經束,或是直接加入線程組去管理。
3、回看你的程序需求,明顯設計不合理。其實應當創建一個線程池去搞定這個業務需求。
再想想吧。
Ⅲ java中IO和NIO的區別和適用場景
java.NIO包里包括三個基本的組件
lbuffer:因為NIO是基於緩沖的,所以buffer是最底層的必要類,這也是IO和NIO的根本不同,雖然stream等有buffer開頭的擴展類,但只是流的包裝類,還是從流讀到緩沖區,而NIO卻是直接讀到buffer中進行操作。
因為讀取的都是位元組,所以在操作文字時,要用charset類進行編解碼操作。
lchannel:類似於IO的stream,但是不同的是除了FileChannel,其他的channel都能以非阻塞狀態運行。FileChannel執行的是文件的操作,可以直接DMA操作內存而不依賴於CPU。其他比如socketchannel就可以在數據准備好時才進行調用。
lselector:用於分發請求到不同的channel,這樣才能確保channel不處於阻塞狀態就可以收發消息。
面向流與面向緩沖
Java NIO和IO之間第一個最大的區別是,IO是面向流的,NIO是面向緩沖區的。Java
IO面向流意味著每次從流中讀一個或多個位元組,直至讀取所有位元組,它們沒有被緩存在任何地方。此外,它不能前後移動流中的數據。如果需要前後移動從流中讀取的數據,需要先將它緩存到一個緩沖區。Java NIO的緩沖導向方法略有不同。數據讀取到一個它稍後處理的緩沖區,需要時可在緩沖區中前後移動。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩沖區中包含所有您需要處理的數據。而且,需確保當更多的數據讀入緩沖區時,不要覆蓋緩沖區里尚未處理的數據。
補充一點:NIO的buffer可以使用直接內存緩沖區,該緩沖區不在JVM中,性能會比JVM的緩沖區略好,不過會增加相應的垃圾回收的負擔,因為JVM緩沖區的性能已經足夠好,所以除非在對緩沖有特別要求的地方使用直接緩沖區,盡量姿蔽手使用JVM緩沖。
阻塞與非阻塞
Java IO是阻塞式的操作,當一個inputstream或outputstream在進行read()或write()操作時,是一直處於等待狀態的,直到有數據讀/寫入後才進行處理.而NIO是非阻塞式的,當進行讀寫操作時,只會返回當前已經准備好的數據,沒有就返回空,這樣當前線程就可以處理其他的事情,提高了資源的使用率.
與傳統IO的優勢
在老的IO包中,serverSocket和socket都是阻塞式的,因此一旦有大規模的並發行為,而每一個訪問都會開啟一個新線程。這時會有大規模的線程上下文切換操作(因為都在等待,所以資源全都被已有的線程吃掉了),這時無論是等待的線程還是正在處理的線程,響應率都會下降,並且會影響新的線程。
而NIO包中的serverSocket和socket就不是這樣,只要注冊到一個selector中,當有數據放入通道的時候,selector就會得知哪些channel就緒,這時就可以做響應的處理,這樣服務端只有一個線程就可以處理大部分情況(當然有些持續性操作,比如上傳下載一個大文件,用NIO的方式不會比IO好)。
通過兩個圖的比較,可以看出IO是直連的,每跡嫌個請求都給一條線程來處理,但是NIO卻是基於反應堆(selector)來處理,直到讀寫的數據准備好後,才會通知相應的線程來進行處理。一言以蔽之:「selector不會讓channel白占資源,沒事的時候給我去睡覺。」
PS:NIO基於位元組進行傳輸,在IO時要並消注意decode/encode。
更具體的信息請參閱:http://blog.csdn.net/zhansong_1987/article/details/45873861
Ⅳ java中IO阻塞時線程處於什麼狀態
Java中線程有4種狀態: RUNNABLE, BLOCKED, WAITING, TIMED_WAITING
當一個線程運行至 Inputstream.read()發生阻塞時,線程處於RUNNABLE。
Ⅳ Java NIO和IO的區別
JavaNIO和IO之間的主要差別,我會更詳細地描述表中每部分的差異。
IONIO
面向流面向緩沖
阻塞IO非阻塞IO
無選擇器
面向流與面向緩沖
JavaNIO和IO之間第一個最大的區別是,IO是面向流的,NIO是面向緩沖區的。JavaIO面向流意味著每次從流中讀一個或多個位元組,直至讀取所有位元組,它們沒有被緩存在任何地方。此外,它不能前後移動流中的數據。如果需要前後移動從流中讀取的數據,需要先將它緩存到一個緩沖區。JavaNIO的緩沖導向方法略有不同。數據讀取到一個它稍後處理的緩沖區,需要時可在緩沖區中前後移動。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩沖區中包含所有您需要處理的數據。而且,需確保當更多的數據讀入緩沖區時,不要覆蓋緩沖區里尚未處理的數據。
阻塞與非阻塞IO
JavaIO的各種流是阻塞的。這意味著,當一個線程調用read()或write()時,該線程被阻塞,直到有一些數據被讀取,或數據完全寫入。該線程在此期間不能再干任何事情了。JavaNIO的非阻塞模式,使一個線程從某通道發送請求讀取數據,但是它僅能得到目前可用的數據,如果目前沒有數據可用時,就什麼都不會獲取。而不是保持線程阻塞,所以直至數據變的可以讀取之前,該線程可以繼續做其他的事情。非阻塞寫也是如此。一個線程請求寫入一些數據到某通道,但不需要等待它完全寫入,這個線程同時可以去做別的事情。線程通常將非阻塞IO的空閑時間用於在其它通道上執行IO操作,所以一個單獨的線程現在可以管理多個輸入和輸出通道(channel)。
選擇器(Selectors)
JavaNIO的選擇器允許一個單獨的線程來監視多個輸入通道,你可以注冊多個通道使用一個選擇器,然後使用一個單獨的線程來逗選擇地通道:這些通道里已經有可以處理的輸入,或者選擇已准備寫入的通道。這種選擇機制,使得一個單獨的線程很容易來管理多個通道。
NIO和IO如何影響應用程序的設計
無論您選擇IO或NIO工具箱,可能會影響您應用程序設計的以下幾個方面:
1.對NIO或IO類的API調用。
2.數據處理。
3.用來處理數據的線程數。
API調用
當然,使用NIO的API調用時看起來與使用IO時有所不同,但這並不意外,因為並不是僅從一個InputStream逐位元組讀取,而是數據必須先讀入緩沖區再處理。
數據處理
使用純粹的NIO設計相較IO設計,數據處理也受到影響。
在IO設計中,我們從InputStream或Reader逐位元組讀取數據。假設你正在處理一基於行的文本數據流,例如:
Name:Anna
Age:25
Email:[email protected]
Phone:1234567890
該文本行的流可以這樣處理:
BufferedReaderreader=newBufferedReader(newInputStreamReader(input));
StringnameLine=reader.readLine();
StringageLine=reader.readLine();
StringemailLine=reader.readLine();
StringphoneLine=reader.readLine();
請注意處理狀態由程序執行多久決定。換句話說,一旦reader.readLine()方法返回,你就知道肯定文本行就已讀完,readline()阻塞直到整行讀完,這就是原因。你也知道此行包含名稱;同樣,第二個readline()調用返回的時候,你知道這行包含年齡等。正如你可以看到,該處理程序僅在有新數據讀入時運行,並知道每步的數據是什麼。一旦正在運行的線程已處理過讀入的某些數據,該線程不會再回退數據(大多如此)。下圖也說明了這條原則:
(JavaIO:從一個阻塞的流中讀數據)而一個NIO的實現會有所不同,下面是一個簡單的例子:
ByteBufferbuffer=ByteBuffer.allocate(48);
intbytesRead=inChannel.read(buffer);
注意第二行,從通道讀取位元組到ByteBuffer。當這個方法調用返回時,你不知道你所需的所有數據是否在緩沖區內。你所知道的是,該緩沖區包含一些位元組,這使得處理有點困難。
假設第一次read(buffer)調用後,讀入緩沖區的數據只有半行,例如,逗Name:An地,你能處理數據嗎看顯然不能,需要等待,直到整行數據讀入緩存,在此之前,對數據的任何處理毫無意義。
所以,你怎麼知道是否該緩沖區包含足夠的數據可以處理呢看好了,你不知道。發現的方法只能查看緩沖區中的數據。其結果是,在你知道所有數據都在緩沖區里之前,你必須檢查幾次緩沖區的數據。這不僅效率低下,而且可以使程序設計方案雜亂不堪。例如:
ByteBufferbuffer=ByteBuffer.allocate(48);
intbytesRead=inChannel.read(buffer);
while(!bufferFull(bytesRead)){
bytesRead=inChannel.read(buffer);
}
bufferFull()方法必須跟蹤有多少數據讀入緩沖區,並返回真或假,這取決於緩沖區是否已滿。換句話說,如果緩沖區准備好被處理,那麼表示緩沖區滿了。
bufferFull()方法掃描緩沖區,但必須保持在bufferFull()方法被調用之前狀態相同。如果沒有,下一個讀入緩沖區的數據可能無法讀到正確的位置。這是不可能的,但卻是需要注意的又一問題。
如果緩沖區已滿,它可以被處理。如果它不滿,並且在你的實際案例中有意義,你或許能處理其中的部分數據。但是許多情況下並非如此。下圖展示了逗緩沖區數據循環就緒地:
3)用來處理數據的線程數
NIO可讓您只使用一個(或幾個)單線程管理多個通道(網路連接或文件),但付出的代價是解析數據可能會比從一個阻塞流中讀取數據更復雜。
如果需要管理同時打開的成千上萬個連接,這些連接每次只是發送少量的數據,例如聊天伺服器,實現NIO的伺服器可能是一個優勢。同樣,如果你需要維持許多打開的連接到其他計算機上,如P2P網路中,使用一個單獨的線程來管理你所有出站連接,可能是一個優勢。一個線程多個連接的設計方案如
JavaNIO:單線程管理多個連接
如果你有少量的連接使用非常高的帶寬,一次發送大量的數據,也許典型的IO伺服器實現可能非常契合。下圖說明了一個典型的IO伺服器設計:
JavaIO:一個典型的IO伺服器設計-一個連接通過一個線程處理
Ⅵ java中的阻塞什麼意思
你說的應該是線程的阻塞狀態吧,從這個詞的意思來講,阻塞指的是暫停一個線程的執行以等待某個條件發生,那在java中如果要主動實現這種狀態可以調用線程的sleep方法或者wait方法等。
Ⅶ Java NIO和IO的區別
Java
NIO和IO的主要區別如下:
1.NIO
的創建目的是為了讓
Java
程序員可以實現高速
I/O
而無需編寫自定義的本機代碼。NIO
將最耗時的
I/O
操作(即填充和提取緩沖區)轉移回操作系統,因而可以極大地提高速度。傳統的IO操作屬於阻塞型,嚴重影響程序的運行速度。
2,。流與塊的比較。原來的
I/O
庫(在
java.io.*中)
與
NIO
最重要的區別是數據打包和傳輸的方式。正如前面提到的,原來的
I/O
以流的方式處理數據,而
NIO
以塊的方式處理數據。
面向流
的
I/O
系統一次一個位元組地處理數據。一個輸入流產生一個位元組的數據,一個輸出流消費一個位元組的數據。為流式數據創建過濾器非常容易。鏈接幾個過濾器,以便每個過濾器只負責單個復雜處理機制的一部分,這樣也是相對簡單的。不利的一面是,面向流的
I/O
通常相當慢。
3.一個
面向塊
的
I/O
系統以塊的形式處理數據。每一個操作都在一步中產生或者消費一個數據塊。按塊處理數據比按(流式的)位元組處理數據要快得多。但是面向塊的
I/O
缺少一些面向流的
I/O
所具有的優雅性和簡單性。
Ⅷ java寫文件怎麼減少io壓力
方法有:使用緩沖區、使用NIO。
1、使用緩沖區:在讀寫文件時,可以使用緩沖區來減少I/O操作的次數,從而減少I/O壓力。例如,可以使用BufferedReader和BufferedWriter類來讀寫文本文件,支握絕持緩沖讀寫。
2、使用NIO:Java的NIO(NewI/O)功能可以使用非阻塞I/O操作,使用了I/O多路復用的機制,可以在一祥蘆個線程中處理多個I/O操作,從而減少線程的創建和銷毀,降低了I/O壓謹皮帶力。
Ⅸ Java:什麼叫做同步非阻塞IO呢
這個IO不用等待對方返回結果,打開IO指令執行完成後,會繼續執行指令後面的操作,當對方返回數據後會出發一個事件,告訴你數據回來了,例如使用selector的非阻塞IO.你應當看看java.nio.