您好,欢迎来到华佗小知识。
搜索
您的当前位置:首页jetty源码走读

jetty源码走读

来源:华佗小知识
QueuedThreadPool类介绍:

 继承至AbstractLifeCycle类

 启动时,它里面创建至少八个线程,处理连接事件,由

ConcurrentLinkedQueue进行管理,当线程空闲超过规定时间,会线程相应线程的生命周期,即通过return结束run方法中的循环来结束线程

 它里面有一个任务管理队列BlockingQueue,创建的线程就是执行它

里面的任务

 其中有一个匿名Runnable实例,创建线程是对它的封装,并在其中实

现了run方法,该方法中主要工作是:a.扫描任务队列,并执行任务,b.看是否有空闲 ,关闭空闲线程

 其对外提供的一个比较重要的接口为dispatch(Runnable job),外

部调用这个方法,往其任务管理队列中放任务,方法具体如下:

public boolean dispatch(Runnable job) {

if (isRunning()) {

final int jobQ = _jobs.size();//获取任务队列的大小 final int idle = getIdleThreads();//获取空闲线程的数量 if(_jobs.offer(job))//将任务插入到队列

{

// If we had no idle threads or the jobQ is greater than the idle threads

if (idle==0 || jobQ>idle) {

int threads=_threadsStarted.get();

if (threads<_maxThreads) //若已启动的线程不够且没超过最大线程时,再创建线程

startThread(threads); }

return true; } }

return false;

}

 创建线程方法

private boolean startThread(int threads) {

boolean started = false; try { }

return started; }

Thread thread = newThread(_runnable);// thread.setDaemon(_daemon); thread.setPriority(_priority);

thread.setName(_name + \"-\" + thread.getId()); _threads.add(thread);// 将新创建的线程放放线程队列 thread.start();// 启动线程 started = true; if (!started)

_threadsStarted.decrementAndGet();

final int next = threads + 1;// 将线程数量增加1 // 校验线程数量是否一致,若线程数量与threads,刚增加线程数量 if (!_threadsStarted.compareAndSet(threads, next))

return false;

} finally {

Conntect系列类介绍:

 Connector是其共有接口

 AbstractConnector抽象类实现的Connector接口,它有一个比较重要

的成员变量:线程数组,数组大小默认为1个,该数组的元素真正是在QueuedThreadPool中创建的,它里面还有一个实现Runnable接口的内部类Acceptor,它的主要作用是接收客户端连接,具体为调用AbstractConnector

类子类的

accept

方法,如下是

SelectChannelConnector的实现

public void accept(int acceptorID) throws IOException {

ServerSocketChannel server = _acceptChannel; if (server != null && server.isOpen()) {

SocketChannel channel = _acceptChannel.accept(); channel.configureBlocking(false); Socket socket = channel.socket(); configure(socket);

_manager.register(channel);//最终将收到的socket放到SelectSet

的ConcurrentLinkedQueue _changes = new ConcurrentLinkedQueue();队列 }

}

Acceptor是在AbstractConnector的doStart方法中实例化的,doStart方法会在Server的start()中调用

关键点如下:

for (int i = 0; i < _acceptorThread.length; i++)

_threadPool.dispatch(new Acceptor(i)); _threadPool是QueuedThreadPool

的实例

 SelectChannelConnector中有一个内部类

ConnectorSelectorManager,它继承自SelectorManager, SelectorManager中有一个SelectSet数组,大小默认是1,SelectSet中拥有一个Selector,SelectSet还有一个ConcurrentLinkedQueue _changes = new

ConcurrentLinkedQueue(),如收到的连接请求,会放到此队列中

 SelectChannelConnector类会根据Acceptor实例的数量创建匿名类

Runnable接口,通过ConnectorSelectorManager最终将此Runnable实例分发给QueuedThreadPool的实例的dispatch方法,run方法的主要任务是:通过ConnectorSelectorManager的doSelect方法调用SelectSet的doSelect()方法,该方法扫描_changes队列,根据不同事件不同,注册到Selector中

1、 SelectChannelConnector的构造函数中计算可以创建Acceptor的数量,计算方法如

下:

public SelectChannelConnector() { }

_manager.setMaxIdleTime(getMaxIdleTime()); setAcceptors(Math.max(1,

(Runtime.getRuntime().availableProcessors() + 3) / 4));

2、

说明:第4步调用AbstractConnector后,还会继续调用其父类HttpBuffers的doStart方法,构造request、response的缓存区

_requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,g

etMaxBuffers());

_responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers());

收到请求处理

首先线程会不断调用SelectSet的doSelect方法,一旦有对应事件发生,发请求过来,会执行以下代码:

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo0.cn 版权所有 湘ICP备2023017654号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务