Netty对内存使用做了极大的优化,一个存储Listeners的容器都没有直接使用List,而是自定义实现,每次扩容2个,因为Listeners每次使用时并不会设置太多,使用List会浪费一点点内存。
package io.netty.util.concurrent;
import java.util.EventListener;
//Netty所有IO操作都是异步的,通过设置回调来处理成功失败等业务
public interface GenericFutureListener<F extends Future<?>> extends EventListener {
void operationComplete(F future) throws Exception;
}
package io.netty.util.concurrent;
import java.util.Arrays;
//Netty中存储监听器的容器-对内存占用做了优化
final class DefaultFutureListeners {
//数组存储监听器
private GenericFutureListener<? extends Future<?>>[] listeners;
private int size;
private int progressiveSize; // the number of progressive listeners
@SuppressWarnings("unchecked")
DefaultFutureListeners(
GenericFutureListener<? extends Future<?>> first, GenericFutureListener<? extends Future<?>> second) {
//构造时先创建长度为2的数组
listeners = new GenericFutureListener[2];
//存储一个对象
listeners[0] = first;
//存储一个对象
listeners[1] = second;
size = 2;
//GenericProgressiveFutureListener类型则++变量
if (first instanceof GenericProgressiveFutureListener) {
progressiveSize ++;
}
if (second instanceof GenericProgressiveFutureListener) {
progressiveSize ++;
}
}
//再次添加监听器对象
public void add(GenericFutureListener<? extends Future<?>> l) {
GenericFutureListener<? extends Future<?>>[] listeners = this.listeners;
//size等于数组长度需要扩容到原来2倍
final int size = this.size;
if (size == listeners.length) {
this.listeners = listeners = Arrays.copyOf(listeners, size << 1);
}
//size位置存储L
listeners[size] = l;
//size++
this.size = size + 1;
//progressiveSize++
if (l instanceof GenericProgressiveFutureListener) {
progressiveSize ++;
}
}
public void remove(GenericFutureListener<? extends Future<?>> l) {
final GenericFutureListener<? extends Future<?>>[] listeners = this.listeners;
int size = this.size;
//循环素组
for (int i = 0; i < size; i ++) {
//找到素组下标
if (listeners[i] == l) {
//0 1 2 3 siez=4
int listenersToMove = size - i - 1;
// int listenersToMove = size - (i + 1); //数组下标从1开始,原来是从0开始
// listenersToMove 的值就是当前元素位置后面还有几个元素
// 如果大于0说面后面还有listenersToMove这些个元素,需要往前移动
if (listenersToMove > 0) {
//从当前i+i位置往前移动,移动listenersToMove个元素,这样就丢弃了i位置的元素。
System.arraycopy(listeners, i + 1, listeners, i, listenersToMove);
}
//最后一个元素就是多余的,设置为空
listeners[-- size] = null;
this.size = size;
if (l instanceof GenericProgressiveFutureListener) {
progressiveSize --;
}
return;
}
}
}
public GenericFutureListener<? extends Future<?>>[] listeners() {
return listeners;
}
public int size() {
return size;
}
public int progressiveSize() {
return progressiveSize;
}
}