Java基础
2020-11-04 14:51:05 0 举报
AI智能生成
登录查看完整内容
Java基础总结
作者其他创作
大纲/内容
hashCode和equals
equals 和 == 的区别
hashCode在HashMap,HashSet之中的用处
方法重载和重写
方法重载的优先级
内部类和静态内部类
实例化顺序
char能否存一个中文字符
多继承的解决方式
内部类
多interface
io
文件IO
流
按格式划分
字节流
字符流
字节流有Input/OutputStream字符流有Reader/Writer字样
按传输方向划分
输入流
输出流
输入流有Input字样,表示从别的地方输入到内存,输出流有Output字样,表示从内存输出到其它地方
常用的流
文件字节流
FileInputStreamFileOutputStream
文件字符流
FileReader
FileWriter
动态字节数组流
ByteArrayInputStream
ByteArrayOutputStream
装饰者字节流
DataOutputStream
DataInputStream
缓存流
BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter
nio中的FileChannel
IO模型,从操作系统角度出发
阻塞IO模型
文件
隔壁的流都是阻塞io模型
网络
socket
非阻塞 IO 模型
现实情况很少见这种使用案例
多路复用 IO 模型
select/poll
信号驱动 IO 模型
select/epoll
异步 IO 模型
linux之中没有实现,windows之中有实现
AsynchronousFileChannel
java7中的aio只是一个伪实现
Java体系中IO
oio/io
阻塞模型
FileInputStream/FileOuptStream
FileWriter/FileRead
nio
使用的是select/poll
三个核心部件
Channel
网络IO
FileChannel
Java NIO中的FileChannel是一个连接到文件的通道。可以通过文件通道读写文件。
FileChannel的使用步骤
打开FileChannel
FileChannel.open()
FileInputStream/FileOutputStream.getChannel()
RandomAccessFIle.getChannel()
声明buffer
ByteBuffer buf = ByteBuffer.allocate(48);
读写数据
读数据
ByteBuffer buf = ByteBuffer.allocate(48);int bytesRead = inChannel.read(buf);
写数据
String newData = \"New String to write to file...\" + System.currentTimeMillis();ByteBuffer buf = ByteBuffer.allocate(48);buf.clear();buf.put(newData.getBytes());buf.flip();while(buf.hasRemaining()) {\tchannel.write(buf);}
关闭FileChannel
channel.close();
零拷贝
mmap
transferTo
transferFrom
DatagramChannel
UDP协议
使用
SocketChannel
TCP协议
使用5大步骤
打开 SocketChannel
SocketChannel socketChannel = SocketChannel.open();
选择阻塞模式/非阻塞模式
默认阻塞模式
非阻塞模式
socketChannel.configureBlocking(false);
创建连接
读
ByteBuffer buf = ByteBuffer.allocate(48);int bytesRead = socketChannel.read(buf);
写
String newData = \"New String to write to file...\" + System.currentTimeMillis();ByteBuffer buf = ByteBuffer.allocate(48);buf.clear();buf.put(newData.getBytes());buf.flip();while(buf.hasRemaining()) { channel.write(buf);}
关闭 SocketChannel
socketChannel.close();
ServerSocketChannel
打开 ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel .configureBlocking(false);
监听新进来的连接
处理新连接
关闭 ServerSocketChannel
serverSocketChannel.close();
Selector
Selector能够处理多个通道
Selector使用一般有4个步骤
创建一个Selector
Selector selector = Selector.open();
向Selector注册通道
register()方法的第二个参数
Connect
SelectionKey.OP_CONNECT
Accept
SelectionKey.OP_ACCEPT
Read
SelectionKey.OP_READ
Write
SelectionKey.OP_WRITE
如果你对不止一种事件感兴趣,那么可以用“位或”操作符将常量连接起来
int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
register() 返回值:SelectionKey
SelectionKey 有如下属性
interest集合
interest集合是你所选择的感兴趣的事件集合。
ready集合
ready 集合是通道已经准备就绪的操作的集合。
这个就是之前注册那个Channel,只是为了访问方便
这个就是注册的selector,这样设计只是为了访问方便
附加的对象(可选)
可以将一个对象或者更多信息附着到SelectionKey上,这样就能方便的识别某个给定的通道。
选择通道 selector.select()
select()方法
int select()
阻塞到至少有一个通道在你注册的事件上就绪了。
int select(long timeout)
select(long timeout)和select()一样,除了最长会阻塞timeout毫秒(参数)。
int selectNow()
不会阻塞,不管什么通道就绪都立刻返回
对感兴趣的事件做出回应 selectedKeys()
Set<SelectionKey> selectedKeys = selector.selectedKeys();
一般有两种处理方式
1. 使用第二步的注册通道的时候的SelectedKey代表的通道,判断是否是这个通道做对应通道感兴趣的事情
2. 遍历所有感兴趣的事情,做出回应
两个特殊的方法
wakeUp()
close()
Buffer
ByteBufferCharBufferDoubleBufferFloatBufferIntBufferLongBufferShortBuffer
capacity
作为一个内存块,Buffer有一个固定的大小值,也叫“capacity”.你只能往里写capacity个byte、long,char等类型。一旦Buffer满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据。
position
当你写数据到Buffer中时,position表示当前的位置。初始的position值为0.当一个byte、long等数据写到Buffer后, position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity – 1。当读取数据时,也是从某个特定位置读。当将Buffer从写模式切换到读模式,position会被重置为0. 当从Buffer的position处读取数据时,position向前移动到下一个可读的位置。
limit
在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。 写模式下,limit等于Buffer的capacity。当切换Buffer到读模式时, limit表示你最多能读到多少数据。因此,当切换Buffer到读模式时,limit会被设置成写模式下的position值。换句话说,你能读到之前写入的所有数据(limit被设置成已写数据的数量,这个值在写模式下就是position)
Buffer读写数据一般遵循以下四个步骤
1. 写入数据到Buffer
从Channel写到Buffer的例子
int bytesRead = inChannel.read(buf); //read into buffer.
通过put方法写Buffer的例子
buf.put(127);
2. 调用flip()方法
flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值。换句话说,position现在用于标记读的位置,limit表示之前写进了多少个byte、char等 —— 现在能读取多少个byte、char等。
3. 从Buffer中读取数据
从Buffer中读取数据有两种方式
从Buffer读取数据到Channel。
int bytesWritten = inChannel.write(buf);
使用get()方法从Buffer中读取数据。
byte aByte = buf.get();
重读
rewind()
Buffer.rewind()将position设回0,所以你可以重读Buffer中的所有数据。limit保持不变,仍然表示能从Buffer中读取多少个元素(byte、char等)。
4. 调用clear()方法或者compact()方法
clear()方法会清空整个缓冲区。
compact()方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。
基本用法
MappedByteBuffer
这是一种特殊的buffer
Channel vs Buffer vs Selector
Channel vs Buffer
Channel 是双向的
既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
通道可以异步地读写。
Channel中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。
Scatter/Gather
scatter
代码实例
gather
Pipe
Java NIO 管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。
Pipe原理的图
创建管道
Pipe pipe = Pipe.open();
向管道写数据
Pipe.SinkChannel sinkChannel = pipe.sink(); //要向管道写数据,需要访问sink通道。String newData = \"New String to write to file...\" + System.currentTimeMillis();ByteBuffer buf = ByteBuffer.allocate(48);buf.clear();buf.put(newData.getBytes());buf.flip();while(buf.hasRemaining()) { sinkChannel.write(buf);}
从管道读取数据
Pipe.SourceChannel sourceChannel = pipe.source(); //从读取管道的数据,需要访问source通道ByteBuffer buf = ByteBuffer.allocate(48);int bytesRead = sourceChannel.read(buf); //read()方法返回的int值会告诉我们多少字节被读进了缓冲区。
Path
Java NIO 2 中的一个定位资源的工具类
Files
Java NIO 2 中的一个文件操作类
Files.exists()Files.createDirectory()Files.copy()Files.move()Files.delete()Files.walkFileTree()
io vs nio
面向流与面向缓冲
Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。
阻塞与非阻塞IO
Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。 Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。
io 效率不一定比nio慢,Files.copy() 使用的就是io的文件流,但是效率比nio还快,nio的优势在于高并发。io需要阻塞。
Reactor模式
C10K问题
单线程单Reactor模型
多线程单Reactor模型
多线程多Reactor模型
Java基础
面向对象/面向过程
面向对象的特征
instanceof vs isAssignableForm
什么是隐式转换,什么式显式转换
什么是装箱,什么是拆箱
error 和 exception
String vs StringBuilder vs StringBuffer
字符串常量池
什么是注解
0 条评论
回复 删除
下一页