笔记

Inventory 清单


* Bootstrap class loader:虚拟机运行时必须要用到的类的加载器,比如java.*。它通常是在虚拟机种用本地代码(如C)实现,在系统中用null表示。 
* Extension class loader:负责加载ext目录下的Class。 
* Application class loader:负责加载CLASSPATH上的类。




  ClassLoader加载Class的步骤: 
检查这个Class是否已经被加载过了
如果没有被加载过,那么让父ClassLoader尝试去加载
如果父ClassLoader无法加载,那么尝试使用当前ClassLoader加载




每个ClassLoader加载Class的过程是:
1.检测此Class是否载入过(即在cache中是否有此Class),如果有到8,如果没有到2
2.如果parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到4
3.请求parent classloader载入,如果成功到8,不成功到5
4.请求jvm从bootstrap classloader中载入,如果成功到8
5.寻找Class文件(从与此classloader相关的类路径中寻找)。如果找不到则到7.
6.从文件中载入Class,到8.
7.抛出ClassNotFoundException.
8.返回Class.




每一个Class Loader都有一个Parent。如果在创建Class Loader时不显式指定其父Class Loader,JVM会把系统Class Loader指定为该Class Loader的Parent。每一个Class Loader都有自己对应的Loaded Class Cache,换句话说,Loaded Class Cache由两部分组成:ClassLoader,以及由它加载的Class类名。


一个已经加载的类是无法被更新的,如果试图用同一个ClassLoader再次加载 同一个类,会得到异常java.lang.LinkageError: duplicate class definition。只能够重新创建一个新的ClassLoader实例来再次加载新类。




当创建自己的ClassLoader时,需要继承java.lang.ClassLoader或者它的子类。在实例化每个ClassLoader对 象时,需要指定一个父对象;如果没有的话,系统自动指定ClassLoader.getSystemClassLoader()为父对象。










-------------------------------------------------------------------------------------------------------------------------------------










当我们引入ExecutionHandler后,原本同步的ChannelHandler链在经过 ExecutionHandler后就结束了,它会被ChannelFactory的worker线程池所回收,而剩下的ChannelHandler链将由ExecutionHandler的线程池接手处理。


Netty整体架构很清晰的分成2个部分,ChannelFactory和ChannelPipelineFactory,前者主要生产网络通信相关的Channel实例和ChannelSink实例,Netty提供的ChannelFactory实现基本能够满足绝大部分用户的需求,当然你也可以定制自己的ChannelFactory,后者主要关注于具体传输数据的处理,同时也包括其他方面的内容,比如异常处理等等,只要是你希望的,你都可以往里添加相应的handler,一般ChannelPipelineFactory由用户自己实现,因为传输数据的处理及其他操作和业务关联比较紧密,需要自定义处理的handler。






使用Netty的步骤实际上已经非常明确了,比如面向连接的Netty服务端客户端使用,第一步:实例化一个BootStrap,并且通过构造方法指定一个ChannelFactory实现,第二步:向bootstrap实例注册一个自己实现的ChannelPipelineFactory,第三步:如果是服务器端,bootstrap.bind(new InetSocketAddress(port)),然后等待客户端来连接,如果是客户端,bootstrap.connect(new InetSocketAddress(host,port))取得一个future,这个时候Netty会去连接远程主机,在连接完成后,会发起类型为CONNECTED的ChannelStateEvent,并且开始在你自定义的Pipeline里面流转,如果你注册的handler有这个事件的响应方法的话那么就会调用到这个方法。在此之后就是数据的传输了






用什么样的网络事件响应处理机制对于网络吞吐量是非常重要的,Netty采用的是标准的SEDA(Staged Event-Driven Architecture)架构[http://en.wikipedia.org/wiki/ Staged_event-driven_architecture],其所设计的事件类型,代表了网络交互的各个阶段,并且在每个阶段发生时,触发相应事件交给初始化时生成的pipeline实例进行处理。事件处理都是通过Channels类的静态方法调用开始的,将事件、channel传递给channel持有的Pipeline进行处理,Channels类几乎所有方法都为静态,提供一种Proxy的效果(整个工程里无论何时何地都可以调用其静态方法触发固定的事件流转,但其本身并不关注具体的处理流程)。


Channels部分事件流转静态方法
1.fireChannelOpen 2.fireChannelBound 3.fireChannelConnected 4.fireMessageReceived 5.fireWriteComplete 6.fireChannelInterestChanged 
7.fireChannelDisconnected 8.fireChannelUnbound 9.fireChannelClosed 10.fireExceptionCaught 11.fireChildChannelStateChanged






一个Channel需要由一个EventLoop来绑定,而且两者一旦绑定就不会再改变。一般情况下一个EventLoopGroup中的EventLoop数量会少于Channel数量,那么就很有可能出现一个多个Channel公用一个EventLoop的情况,这就意味着如果一个Channel中的EventLoop很忙的话,会影响到这个Eventloop对其它Channel的处理,这也就是为什么我们不能阻塞EventLoop的原因。

你可能感兴趣的:(笔记)