传统IO有两种形式,一种是阻塞IO,另一种是阻塞IO+每个请求创建线程/线程池。
阻塞IO
IO的阻塞、非阻塞主要表现在一个IO操作过程中,如果有些操作很慢,比如读操作时需要准备数据,那么当前IO进程是否等待操作完成,还是得知暂时不能操作后先去做别的事情?一直等待下去,什么事也不做直到完成,这就是阻塞。抽空做些别的事情,这是非阻塞。
在传统IO里,InputStream.read()方法时是阻塞的,它会一直等到数据到来时(或超时)才会返回;同样,在网络IO运用中调用ServerSocket.accept()方法时,也会一直阻塞到有客户端连接才会返回。
以网络IO操作为例:
public static void main(String[] args) { Socket socket = null; try { ServerSocket ss = new ServerSocket(10000); while (true) { socket = ss.accept();//阻塞 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String msg = null; while((msg = in.readLine()) != null){//readLine阻塞方法 System.out.println(msg); } } } catch (Exception e) { e.printStackTrace(); } finally{ if(socket != null){ socket.close(); } } }
这种阻塞IO的缺陷如下:
- 在调用InputStream.read()/buffer.readLine()方法时是阻塞的,它会一直等到数据到来或缓冲区已满时或超时时才会返回,并且产生了大量String类型垃圾,尽管可以使用StringBuffer优化。
- 在调用ServerSocket.accept()方法时,也会一直阻塞到有客户端连接才会返回。
- 由于服务器端是单线程的,在第一个连接的客户端阻塞了线程后,第二个客户端必须等待第一个断开后才能连接。
- 所有的客户端连接在请求服务端时都会阻塞住,等待前面的完成。即使是使用短连接,数据在写入 OutputStream 或者从 InputStream 读取时都有可能会阻塞。这在大规模的访问量或者系统对性能有要求的时候是不能接受的。
阻塞IO + 每个请求创建线程
为每个客户端请求创建单独的线程是对传统的阻塞式IO最常见的解决办法,示例如下:
public static void main(String[] args) { try { ServerSocket ss = new ServerSocket(10000); while (true) { final Socket socket = ss.accept();//阻塞 new Thread(){ public void run(){ try{ BufferedReader in = new BufferedReader(new InputStreamReader( socket.getInputStream())); String msg = null; while((msg = in.readLine()) != null){//readLine阻塞方法 System.out.println(msg); } }catch(Exception e){ e.printStackTrace(); } finally{ if(socket != null){ socket.close(); } } } }.start(); } } catch (Exception e) { e.printStackTrace(); } }这种方式的IO操作模式虽然解决了服务端为单线程的缺陷,但是还是有很多缺陷:
相关推荐
Java NIO(New IO)是Java 1.4引入的新特性,是对传统IO的一个补充。NIO提供了非阻塞的IO操作,通过Channel和Buffer对象实现。通道(Channel)类似于流,但它们是双向的,可以同时用于读写。缓冲区(Buffer)是用来...
- Java传统IO基于流,分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),以及它们的缓冲流和转换流。 - 流是单向的,数据只能从源到目标进行传输,无法同时进行读写操作。 - 传统IO基于阻塞I/O...
此外,Java NIO(New IO)在Java 1.4引入,是对传统IO的补充,提供了非阻塞IO、选择器和通道等高级特性。NIO的设计也遵循了类似的原则,虽然不是严格意义上的Decorator模式,但同样可以动态组合不同的通道和缓冲区,...
然而,传统的IO模型在处理大量并发连接时表现出效率较低的问题,为了解决这个问题,Java引入了NIO(Non-blocking Input/Output)模型。 **Java IO核心概念** Java IO的核心类包括InputStream、OutputStream、Reader...
- `Channel` 类似于传统IO的流,但可以同时进行读写操作,并且可连接到多个数据源或目标。 - `Selector` 允许单线程监控多个通道,当通道准备就绪时,选择器会通知程序员进行相应的操作,提高了并发处理能力。 5....
虽然NIO流不在传统的IO流框架内,但了解其工作原理对于高级IO操作至关重要。 在实例开发中,我们可能会遇到文件复制、网络数据传输、日志记录等各种场景。例如,我们可以使用FileInputStream和FileOutputStream实现...
7. 集合流(Collecting Streams):Java 8引入了集合流(Stream API),这与传统的IO流不同,它用于处理集合数据,支持函数式编程风格,提供了丰富的操作,如filter、map、reduce等。 8. 文件系统API:Java NIO...
NIO的核心是Channel和Buffer,Channel类似于传统IO中的流,但可以同时进行读写操作;Buffer用于存储数据,用户需要先将数据写入Buffer,然后通过Channel传输。 正则表达式(Regular Expression,简称regex)是一种...
Channels代表连接到数据源或目标的通道,Selector用于多路复用多个通道,Buffers则替代了传统IO中的缓冲区。 过滤流(Filter Stream)是Java IO的一个重要设计模式,它在原有流的基础上增加额外功能,如数据转换、...
Doug Lea在书中探讨了Java的NIO(New IO)框架,它是对传统IO的一个重大改进。NIO引入了非阻塞IO和选择器(Selector),允许一个线程同时管理多个通道(Channel),极大地提高了系统在处理并发IO请求时的效率。通过...
与传统的IO相比,NIO更注重于通道(Channels)和缓冲区(Buffers)的使用,而非流。NIO的主要优点在于其非阻塞特性,可以在等待数据可用时进行其他处理,提高了系统的并发性能。 "Java NIO"这本书可能涵盖了以下...
在Java传统IO中,数据的读写都是通过流来完成,而NIO则引入了通道(Channel)和缓冲区(Buffer)的概念,提供了一种非阻塞的I/O操作方式,极大地提高了Java进行并发I/O处理的能力。 首先,我们来看下NIO的核心组件...
Java中的Scalable IO指的是能够高效处理大量输入输出操作的能力,尤其在面对高并发和大数据量的场景时。在这个主题中,我们主要关注Java的非阻塞I/O(Non-blocking I/O,通常缩写为NIO)框架。NIO自Java 1.4版本引入...
Java NIO(Non-blocking Input/Output) 是Java 1.4版本引入的一种新的I/O模型,它是对传统IO模型的补充,旨在提供更高性能和更灵活的I/O操作。传统IO基于流,而NIO基于通道和缓冲区。 在传统的Java IO模型中,以网络...
高级的文件操作,如文件复制,可以使用NIO(New IO)的Channels和Buffers来实现,这通常比传统的流更高效。 IO_3.pdf可能涵盖了流的管道和过滤器模式。管道流如PipedInputStream和PipedOutputStream,常用于线程间...
- NIO的`Selector`可以监控多个`Channel`,当有数据可用时进行选择操作,避免了传统IO模型的阻塞问题。 - `ByteBuffer`等缓冲区类提供了更灵活的数据操作方式。 7. **File类**: - `java.io.File`类用于文件和...
而在简单的文件读写或网络通信中,传统的IO已经足够。 总的来说,Java IO操作是软件开发中不可或缺的一部分,理解和熟练掌握Java IO能有效提升程序的健壮性和性能。无论是基本的文件操作,还是复杂的网络通信,Java...
在Java编程领域,IO(Input/Output)和NIO(Non-blocking Input/Output)是两种不同的I/O模型,它们在处理数据输入和输出时有着显著的差异。本教程旨在帮助NIO初学者理解这两种模型的核心概念及其实际应用,通过具体...
Java传统的`Socket`和`ServerSocket`类使用的就是阻塞IO。这种模型效率较低,因为CPU可能会浪费时间在等待数据上。 - **非阻塞IO**:非阻塞IO不会挂起进程,即使数据尚未准备好。Java NIO库引入了选择器(Selector...
通道(如FileChannel)和缓冲区(ByteBuffer)是NIO的核心概念,它们与传统的IO流不同,能更好地支持并发。 Java IO的另一个重要方面是流的处理方式,例如使用文件复制作为示例,我们可以看到如何将一个文件的内容...