JAVA特性
基础语法
一、Java程序的命令行工具
二、final、finally、finalize
三、继承
class 父类 {
//代码
}
class 子类 extends 父类 {
//代码
}
四、Vector、ArrayList、LinkedList
五、原始数据类型和包装类
六、接口和抽象类
JAVA进阶
Java引用队列
Object counter = new Object();
ReferenceQueue refQueue = new ReferenceQueue<>();
PhantomReference<Object> p = new PhantomReference<>(counter, refQueue);
counter = null;
System.gc();
try {
// Remove是一个阻塞方法,可以指定timeout,或者选择一直阻塞
Reference<Object> ref = refQueue.remove(1000L);
if (ref != null) {
// do something
}
} catch (InterruptedException e) {
// Handle it
}
JAVA IO
IO 工具类
File
这里是引用
RandomAccessFile
这里是引用
字节流
InputStream和OutputStream。
字符流
Reader和Writer。
补充知识点
Closeable 接口:
try-with-resources、 try-finally
Cleaner 或 finalize 机制:资源释放的最后把关
NIO
1.主要组成
主要由Buffer、Channel、Selector、Charset四部分组成。
Buffer(缓冲区):
NIO 中,数据都是通过 Buffer 处理的; 除了布尔类型,所有原始数据类型都有相应的 Buffer 实现( ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer 和 DoubleBuffer)。
Buffer详细介绍:
Buffer的几个基本属性:capacity、position、limit、mark。
capacity: Buffer的大小,即数组的长度。
position:要操作的数据的起始位置。
limit:操作的限额。(注意,在读取和写入时,limit的意义是不同的)
mark:记录上一次position的位置,但不是必须的。(默认是0)
Channel(通道):
NIO 中被用来支持批量式 IO 操作的一种抽象,可以进行异步的 IO 操作。
常见的 Channel 类有 FileChannel、SocketChannel、ServerSocketChannel 和 DatagramChannel。
Selector(选择器):
Selector 可以用来实现 Reactor 模式,用于监听多个 Channel 的事件。因此,可以检测到注册在 Selector 上的多个 Channel 中,是否有 Channel 处于就绪状态,实现了单线程对多 Channel 的高效管理,是javaNIO 实现多路复用的基础。
Charset:
提供 Unicode 字符串定义。
2.NIO的核心
Buffer 和 Channel 之间的交互:数据可以从 Channel 读取到 Buffer 中,也可以从 Buffer 写入到 Channel 中。
3.NIO的优点
NIO通过高效地定位就绪的 Channel,高效分配任务。仅select 时是阻塞的,所以可以避免大量客户端连接时,频繁切换线程。因此,应用的扩展性有了非常大的提高。
异常处理时的基本原则
补充概念
同步或异步(synchronous/asynchronous)
同步:当我们进行同步操作时,后续的任务是等待当前调用返回,才会进行下一步。
异步:其他任务不需要等待当前调用返回,通常依靠事件、回调等机制来实现任务间次序关系
阻塞与非阻塞(blocking/non-blocking)
阻塞状态:无法从事其他任务,只有当条件就绪才能继续。
非阻塞:不管 IO 操作是否结束,直接返回,相应操作在后台继续处理。
序列化(Serialization)
这里是引用
补充知识点
不能一概而论认为同步或阻塞就是低效。
网络编程中,比如 Socket 通信,都是典型的 IO 操作目标
补充
FileSystemProvider
两种特别的Buffer:Direct Buffer和MappedByteBuffer
DirectBuffer:
DirectBuffer是ByteBuffer的一种特殊形式,用于在堆外(Off-heap)内存中存储数据。
DirectBuffer创建方法:
调用ByteBuffer的allocateDirect()方法来创建。(不是使用传统的allocate()方法)
DirectBuffer的主要特点:
特点 | 内容 |
---|---|
直接访问 | 因为内存是在堆外分配的,所以DirectBuffer对象可以通过JNI(Java Native Interface)直接访问,从而避免了在Java堆和本机堆之间来回复制数据的开销 |
堆外内存存储 | DirectBuffer对象分配的内存不在Java虚拟机的堆中,而是直接在操作系统的本机内存中分配的 |
性能优化 | DirectBuffer适用于需要频繁访问大量数据或需要与本地(native)代码进行交互的场景,它们可以显著提高数据访问和操作的效率,因为避免了额外的内存拷贝。 |
DirectBuffer的使用需要注意:
- 它们的创建和销毁通常比普通的堆上的ByteBuffer更昂贵,因为涉及到操作系统的本机内存管理。
- 对于小数据量的操作,并不一定比普通的堆上操作性能更好,甚至可能更差,因为操作系统在小块内存分配和释放上的开销相对较大。
垃圾收集方面的特殊性。