目录
IO原理
用户IO读写在底层上是调用了read和write系统调用,
但是read和write系统调用并不是直接在内存和物理设备之间交换数据。
就是说,上层程序的IO,并不是物理级别的读写,而是缓存的复制。
read和write系统调用都不负责数据在内核缓冲区和物理设备(如磁盘)之间的交换,
底层的读写交换是由操作系统内核完成的。
缓冲区是为了减少频繁的设备之间的物理交换。
外部设备直接读写,涉及操作系统的中断。
发生系统中断时,需要保存之前的进程数据和状态等信息,结束中断之后,还需要恢复之前的进程数据和状态等信息,就是为了减少这样的底层系统的时间消耗、性能消耗,于是出现内存缓冲区。
上层调用系统调用仅仅是把数据从内核缓冲区复制到上层应用的缓冲区(进程缓冲区),和将数据从进程缓冲区复制到内核缓冲区中。
底层操作系统会对内核缓冲区进行监控,等待缓冲区达到一定数量的时候,再进行IO设备的中断处理,集中执行物理设备的实际IO操作,这种机制提升了系统的性能。至于什么时候中断由操作系统内核决定。
Linux系统中,操作系统内核只有一个内核缓冲区。每个用户进程都有自己的独立的缓冲区(进程缓冲区)。
四种IO模型
同步和异步
- 同步IO:用户空间的线程是主动发起IO请求的一方,内核空间是被动接受方。
- 异步IO:系统内核是主动发起IO请求的一方,用户空间的线程是被动接受方。
同步阻塞IO (Blocking IO) BIO
需要内核IO操作彻底完成之后,才返回到用户空间执行用户的操作。
传统的IO模型都是同步阻塞IO,java中默认创建的socket都是阻塞的。
Java.io包下的类:
InputStream
OutputStream
Reader
Writer
网络编程:
ServerSocket
Socket
阻塞:
read方法 accept方法 阻塞式的
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketBIO{
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(9000,20);
System.out.println("new ServerSocket(9000)");
while(true){
Socket client = server.accept();
//阻塞1 接收客户端
System.out.println(client.getPort());
new Thread(new Runnable(){
//每连接一个客户端new 一个线程
public void run() {
InputStream in = null;
try{
in = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
while(true){
String dataline = reader.readLine();
//阻塞2 虽然连上了,但是不一定发消息
if(null != dataline){
System.out.println(dataline);
}else{
client.close();
break;
}
}
}catch(Exception ex) {
ex.printStackTrace(