Ⅰ 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.