源码高效学习-【Netty】构建只读Map结构
最近在学习Netty 源码结构中 发现了一个有趣的API
Collections.UnmodifiableMap
/**
* 返回指定地图的不可修改视图。 这种方法
* 允许模块为用户提供对内部的“只读”访问
* 地图。 对返回的地图“通读”的查询操作
* 到指定的映射,并尝试修改返回的
* 地图,无论是直接的还是通过其集合视图,都会导致
* <tt>UnsupportedOperationException</tt>.<p>
*
* 如果指定的地图,返回的地图将是可序列化的
* 是可序列化的。
*
* @param <K> 映射键的类
* @param <V> 地图值的类
* @param m 要为其返回不可修改视图的地图。
* @return 指定地图的不可修改视图。
*/
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
return new UnmodifiableMap<>(m);
}
这个API 方法通过注释说明很简单 就是构建一个只读Map 结构
事例:
public static void TestMap(){
//构建Map
Map<String,String> params=new HashMap<>();
params.put("张三","38");
params.put("李四","42");
params.put("王五","42");
params.forEach((k,v)->{
System.out.println(k);
System.out.println(v);
});
//构建只读读取
Map<String,String> readOnlyMap=Collections.unmodifiableMap(params);
readOnlyMap.forEach((k,v)->{
System.out.println(k);
System.out.println(v);
});
readOnlyMap.put("李四","王五");
}
-----------------------------测试结果-----------------------------
李四
42
张三
38
王五
42
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableMap.put(Collections.java:1457)
at com.zkh360.pipeline.test.demo.DemoBootStrap.TestMap(DemoBootStrap.java:113)
at com.zkh360.pipeline.test.demo.DemoBootStrap.main(DemoBootStrap.java:28)
Netty源码 使用
Netty 在构建Channel 模型时候,ServerBootstrap 会初始化一个ChannelOption的配置类
ChannelOption 作用
初始化Channel 时候,会构建一个当前管道 中相关参数
例如:I/O网络的超时时间,连接池大小等
/**
* {@link ChannelOption} 允许以类型安全的方式配置 {@link ChannelConfig}
* 道路。 支持哪个 {@link ChannelOption} 取决于实际实现
* {@link ChannelConfig} 并且可能取决于它所属的传输的性质
* 到。
* * @param <T> 对 {@link ChannelOption} 有效的值的类型
*/
public class ChannelOption<T> extends AbstractConstant<ChannelOption<T>> {
private static final ConstantPool<ChannelOption<Object>> pool = new ConstantPool<ChannelOption<Object>>() {
@Override
protected ChannelOption<Object> newConstant(int id, String name) {
return new ChannelOption<Object>(id, name);
}
};
这思想比较巧妙的一个点:
Netty管道配置设计 Map<ChannelOption<?>, Object>
设计者 设计时候配置时候遵循两点思想:
- 初始化时候可以Map 允许被写入的
- 模型传递的过程是不可以修改的,但是是可以在Channel 管道中获取的。
因此在获取时采用集合中UnmodifiableMap方法 复制一个只读Map视图结构。
final Map<ChannelOption<?>, Object> options() {
synchronized (options) {
return copiedMap(options);
}
}
static <K, V> Map<K, V> copiedMap(Map<K, V> map) {
if (map.isEmpty()) {
return Collections.emptyMap();
}
return Collections.unmodifiableMap(new HashMap<K, V>(map));
}
这样就更好的保证了当前框架的可靠性。