离职后第三天,一直在家坐着有点抑郁,以下是复习内容:
一、Java IO复习
所有字节流的父类:InputStream/OutputStream
所有字符流的父类: Reader/Writer
字节流可以处理所有类型数据,字符流只可以处理字符数据。处理纯文本数据,优先考虑字符流;字符流会用缓冲区。
1. 常用流
文件输入输出流:FileInputStream和FileOutputStream
FileOutputStream fos = new FileOutputStream("test.log")
FileOutputStream fos = new FileOutputStream("test.log", true) //第二个参数为true表示追加到已经存在的文件
桥梁流:InputStreamReader和OutputStreamWriter //字节流转化成字符流的桥转换器
逐行读写流: BufferedReader/BufferedWriter //过滤流,需要其他节点流作参数构造对象
管道流:PipedInputStream/PipedOutputStream //线程交互的时候使用;管道输出流和管道输入流需要对接
数据流:DataInputStream和DataOutputStream //通过流读取Java基本类
对象流:ObjectInputStream和ObjectOutputStream //实现对象序列化;过滤流,需要节点流作参数构造对象
2. NIO
为很么需要NIO?
基本套接字对于小规模的系统可以很好的运行,但是当涉及到上千个客户端的服务器时,可能就会产生很多问题。由于创建、维护和切换线程需要的系统开销,一客户一线程方式在系统扩展性方面受到了限制。线程池可以节省这种开销,但是线程池太大的话将带来更多的线程开销,所以线程池的大小限制了系统可以服务的线程总数。
最关键的是,使用线程池,程序员几乎不能对什么时候哪个线程将获得服务进行控制!
我们需要一种方法来一次轮询一组客户端,一检查哪个客户端需要服务。
一个channel实例代表了一个可轮询的IO目标。
3. 反应器与主动器
反应器需要程序先注册事件处理器,然后启动反应器的事件循环,不断地检查是否有就绪地IO事件,当有就绪事件时,同步事件多路分解器将会返回到反应器,反应器会将事件分发给多个句柄的回调函数以处理这些事件。
反应器的一个特点是,具体的处理程序并不调用反应器,而是由反应器来通知处理程序去处理事件,这种方式也被成为“控制反转”,又称为“好莱坞原则”。
反应器使用起来相对直观,但是它不能同时支持大量的客户请求或者耗时过长的请求,因为它串行化了所有的事件处理过程。
主动器的步骤:
1)应用程序需要定义一个异步执行的操作,例如socket的异步读写。
2) 执行异步操作,异步事件处理器将异步请求交给操作系统就返回了,让操作系统完成具体操作,操作系统完成操作后,会将完成事件放入一个完成事件队列。
3)异步事件分离器会检测完成事件,若检测到完成事件,则从完成事件队列中取出,并通知应用程序注册的完成事件处理函数去处理。
4)完成事件处理函数处理异步操作的结果。