ThreadPoolExecutor源码学习(2)-- 在thrift中的应用
thrift作为一个从底到上除去业务逻辑代码,可以生成多种语言客户端以及服务器代码,涵盖了网络,IO,进程,线程管理的框架,着实庞大,不过它层次清晰,4层每层解决不同的问题,可以按需取用,相当方便。
+-------------------------------------------+ | Server | -- 服务器进程调度 | (single-threaded, event-driven etc) | +-------------------------------------------+ | Processor | -- RPC接口处理函数分发,IDL定义接口的实现将挂接到这里面 | (compiler generated) | +-------------------------------------------+ | Protocol | -- 协议 | (JSON, compact etc) | +-------------------------------------------+ | Transport | -- 网络传输 | (raw TCP, HTTP etc) | +-------------------------------------------+
其实对于服务端编程的技术大牛来说,服务器调度可能最能体现个人技术功底,但是从传输层,到序列化这层的工作,确实是比较繁琐工作,可以直接利用thrift生成的代码来完成问题。
以上为题外话,在thrift的java代码实现Server这一层有个TThreadPoolServer,里面对于线程管理就是使用ThreadPoolExecutor,下面贴下核心代码
public void serve() { try { serverTransport_.listen(); } catch (TTransportException ttx) { LOGGER.error("Error occurred during listening.", ttx); return; } stopped_ = false; while (!stopped_) { int failureCount = 0; try { TTransport client = serverTransport_.accept(); WorkerProcess wp = new WorkerProcess(client); executorService_.execute(wp);//这个就是ThreadPoolExecutor } catch (TTransportException ttx) { if (!stopped_) { ++failureCount; LOGGER.warn("Transport error occurred during acceptance of message.", ttx); } } } executorService_.shutdown(); // Loop until awaitTermination finally does return without a interrupted // exception. If we don't do this, then we'll shut down prematurely. We want // to let the executorService clear it's task queue, closing client sockets // appropriately. long timeoutMS = options_.stopTimeoutUnit.toMillis(options_.stopTimeoutVal); long now = System.currentTimeMillis(); while (timeoutMS >= 0) { try { executorService_.awaitTermination(timeoutMS, TimeUnit.MILLISECONDS); break; } catch (InterruptedException ix) { long newnow = System.currentTimeMillis(); timeoutMS -= (newnow - now); now = newnow; } } }
值得注意的是在执行完所有任务的时候,需要调用shutdown()方法,这个在网上的很多例子都有,但是对于最后一段作者反复检查状态再退出,这个着实没有必要的,在shutdown()方法中就有类似的代码了(jdk1.7);再者java并不会在主线程退出的情况下会对其他线程造成影响,所以这段代码更显多余:-D