Netty源码中的原型模式之所以有必要单独拿出来讲,是因为Netty有独特的数据结构实现了原型模式,并且还提供了深拷贝的实现思路,所以需要做一个详细的分析。
NonBlockingHashMap
NonBlockingHashMap是Netty用来代替ConcurrentHashMap的数据结构,可以理解为线程安全的HashMap,但与HashMap不同的是,key和value都不可以为null。它和ConcurrentHashMap有一些相似点,扩容时利用多线程加速复制数据,利用数组统计size减少线程竞争。尽管它不会阻塞线程,速度更快,但比ConcurrentHashMap更耗资源,而且伸缩性不好,使用时要做一些取舍。
public class NonBlockingHashMap<TypeK, TypeV>
extends AbstractMap<TypeK, TypeV>
implements ConcurrentMap<TypeK, TypeV>, Cloneable, Serializable {
/**
* Creates a shallow copy of this hashtable. All the structure of the
* hashtable itself is copied, but the keys and values are not cloned.
* This is a relatively expensive operation.
*
* @return a clone of the hashtable.
*/
@Override
public Object clone() {
try {
NonBlockingHashMap<TypeK,TypeV> t = (NonBlockingHashMap<TypeK,TypeV>) super.clone();
t.clear();
// Now copy sanely
for( TypeK K : keySet() ) {
final TypeV V = get(K); // Do an official 'get'
t.put(K,V);
}
return t;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
}
注释写的是clone()方法创建了此数据结构的浅拷贝。它本身的所有结构都会被拷贝,但key和value都不会被拷贝,而是原封不动重新输入新的实例里。因为严格意义上的深拷贝是比较耗费资源的操作。
无独有偶,Netty另一个特色数据结构NonBlockingIdentityHashMap的原型模式实现方式和NonBlockingHashMap一模一样,因此不做赘述。
AbstractBootstrap
AbstractBootstrap是Netty的一个工具类,用于服务器通道的一系列配置,譬如绑定NioEventLoopGroup线程组、指定NIO的模式、指定子处理器、处理workerGroup、指定端口等。其有ServerBootstrap、Bootstrap两个具体的子类。
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable {
// ……代码省略……
/**
* Returns a deep clone of this bootstrap which has the identical configuration. This method is useful when making
* multiple {@link Channel}s with similar settings. Please note that this method does not clone the
* {@link EventLoopGroup} deeply but shallowly, making the group a shared resource.
*/
@Override
@SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException")
public abstract B clone();
// ……代码省略……
}
可见AbstractBootstrap的clone()方法的意义在于提醒子类实现本身的深拷贝,并且要记得给EventLoopGroup也做一个深拷贝。
Bootstrap与原型模式有关的代码如下:
public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel> {
// ……代码省略……
public Bootstrap() { }
private Bootstrap(Bootstrap bootstrap) {
super(bootstrap);
resolver = bootstrap.resolver;
remoteAddress = bootstrap.remoteAddress;
}
@Override
@SuppressWarnings("CloneDoesntCallSuperClone")
public Bootstrap clone() {
return new Bootstrap(this);
}
/**
* Returns a deep clone of this bootstrap which has the identical configuration except that it uses
* the given {@link EventLoopGroup}. This method is useful when making multiple {@link Channel}s with similar
* settings.
*/
public Bootstrap clone(EventLoopGroup group) {
Bootstrap bs = new Bootstrap(this);
bs.group = group;
return bs;
}
// ……代码省略……
}
可见Bootstrap继承的clone()方法并没有对EventLoopGroup成员变量进行深拷贝,而是靠带一个参数的同名方法实现的深拷贝。
ServerBootstrap与原型模式有关的代码如下:
public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel> {
// ……代码省略……
public ServerBootstrap() { }
private ServerBootstrap(ServerBootstrap bootstrap) {
super(bootstrap);
childGroup = bootstrap.childGroup;
childHandler = bootstrap.childHandler;
synchronized (bootstrap.childOptions) {
childOptions.putAll(bootstrap.childOptions);
}
childAttrs.putAll(bootstrap.childAttrs);
}
@Override
@SuppressWarnings("CloneDoesntCallSuperClone")
public ServerBootstrap clone() {
return new ServerBootstrap(this);
}
// ……代码省略……
}
可见ServerBootstrap实现了EventLoopGroup的深拷贝。