首先不得不说这个类 org.apache.tomcat.util.net.JIoEndpoint,它负责所有的TCP请求连接,实现了一个服务器模式,启用一个后台监听 线程,负责接收到来的socket,然后从线程池中取出响应的worker,扔给worker进行处理,自己继续监听。其次worker是一个负责处理 socket的一个线程,就是它带着用户的请求开始进入Tomcat世界的,默认的worker总共有200个,即:最多200个线程。当处理完一个请求 的时候,这个线程并不会销毁,而是进入wait阻塞,这个线程的对象也不会销毁,是进入了一个栈里面,对应workstack那个数据结构。每当接收线程 拿到一个socket的时候,就先从栈里面拿出一个已有的线程对象,然后就利用该对象的assign方法,将这个socket给它,并调用notify重 新唤醒这个worker的处理线程。以后我们做小型服务器的时候,可以借鉴它的实现方式。正在研究多线程的朋友,这个类绝对让你可以学的透彻!
相对应的还有一个 org.apache.tomcat.util.net.NioEndpoint,这个和前面那个功能差不多,但是用了NIO包里的API,有一个最大的 区别就是,接收线程接收一个socket之后,可能会将这个socket先放入缓存池,然后worker从池里面拿socket去处理,比前面那个类看起 来功能和性能都会提升很多,不过代码行有2K多,相当复杂,设计不够精巧,有兴趣可以去研究下。
org.apache.tomcat.util.buf.MessageBytes:这是 一个接近底层的字符串处理类,为什么说是接近底层,是因为socket接收进来的都是字节类型,而java用的是char或者String,这之间的转换 涉及到编码问题和性能问题,所以凡是socket收进来的信息,全部都用这个类表示,只有当要输出字符串的时候,才会将里面的字节进行转换,实现一种延迟 加载的懒模式,被Tomcat底层所使用的Request类,就是大量使用了这个类来存放数据。我们来小小窥视一下,Request类:
- private MessageBytes methodMB = MessageBytes . newInstance () ;
- private MessageBytes unparsedURIMB = MessageBytes . newInstance () ;
- private MessageBytes uriMB = MessageBytes . newInstance () ;
- private MessageBytes decodedUriMB = MessageBytes . newInstance () ;
- private MessageBytes queryMB = MessageBytes . newInstance () ;
- private MessageBytes protoMB = MessageBytes . newInstance () ;
- // remote address/host
- private MessageBytes remoteAddrMB = MessageBytes . newInstance () ;
- private MessageBytes localNameMB = MessageBytes . newInstance () ;
- private MessageBytes remoteHostMB = MessageBytes . newInstance () ;
- private MessageBytes localAddrMB = MessageBytes . newInstance () ;
- private MimeHeaders headers = new MimeHeaders () ;
或许大家会觉得,构造出这么多的类,性能会高到哪里去,其实不是这样的,不停的构造和销毁 对象的确会损耗相当的性能,但是一个对象被构造出来,可以重复利用,那就相当完美了,这个类就是如此的设计,其中有一个回收资源的方法,叫 recycle(),这个方法可以清空里面的数组,清空里面的对象,而不会销毁自己本身,因为使用它的对象,只要调用recycle,以后又可以重复使用 了。
MessageBytes其实内置了2个重要的 类,org.apache.tomcat.util.buf.ByteChunk和 org.apache.tomcat.util.buf.CharChunk,这2个类带我们回到了C时代,为什么这么说?因为它简直就是一个字符串处理 类,一些眼熟的算法全部映入眼帘,比如字符转匹配算法,indexOf,startsWith,判断字符转是否相等,查找字符,等等,比之JDK提供的性 能更好,功能更强大(这句话说过了,呵呵)
还有一个实用的值得学习的数据结构 是,org.apache.tomcat.util.buf.Ascii,如果知道表驱动的朋友们,一定对这个类很熟悉了,判断大小写?判断是不是英文单 词?判断是不是空白符?判断是不是数字,将字节类型转换为int、long类型,大小写转换,等等。这些都是大学计算机课程的课后练习题。