首页 > 代码库 > 多线程端点服务发布程序(摘)

多线程端点服务发布程序(摘)

多线程端点服务发布程序

摘自:JAVA WEB服务:构建与运行

任增刚

《Java Web服务:构建与运行》以示例驱动的方式详尽地介绍了XML Web服务和RESTful Web服务所涵盖的Java相关API,以清晰、务实的方法讲述Web服务相关技术,第1章讲述Java Web服务快速入门。本节说的是多线程端点服务发布程序。

AD: 2014WOT全球软件技术峰会北京站 课程视频发布

 

 

1.10  多线程端点服务发布程序

Multithreading the Endpoint Publisher

以往的例子中,端点发布程序都是单线程的,也就是说在同一时刻只能并发处理一个客户端请求。在处理下一个请求之前,必须要等发布的服务完成当前正在处理的过程。如果当前正在处理的服务请求被挂起,在这个被挂起的请求处理完毕之前,其他后续的服务请求都无法进行。

在正式的产品环境中,Endpoint发布程序需要并发处理多个客户端请求,这样多个不可预期的客户端请求就可以在同一时间被处理。针对底层的计算机系统而言,比如对称多处理器(SMP,symmetric multiprocessor)系统,每一个独立的CPU可以并发地处理不同客户端请求。而在一个单处理器计算机环境中,可以通过时间共享机制来完成同一时间内客户端请求的并发处理。Java语言支持多线程并发处理机制。因此,需要我们解决的就是如何使端点发布程序也支持多线程处理机制。JWS框架支持端点多线程模式,程序人员无须面对复杂而又难以控制的同步块(Synchronized Block)、wait和notify方法调用等。

Endpoint对象有一个定义了标准get/set方法的Executor属性。Excutor用来执行可运行的(Runnable)任务;比如一个Java Thread实例。(Java中Runnable接口只定义了一个无返回值的公共接口方法:run()。)Executor对象对多线程处理来说是一个不错的选择,因为Executor针对被执行任务的提交和管理提供了高度封装。使端点发布程序支持多线程的第一步就是创建一个Executor类,代码如下:

  1. package ch01.ts;  
  2.  
  3. import java.util.concurrent.ThreadPoolExecutor;  
  4. import java.util.concurrent.LinkedBlockingQueue;  
  5. import java.util.concurrent.TimeUnit;  
  6. import java.util.concurrent.locks.ReentrantLock;  
  7. import java.util.concurrent.locks.Condition;  
  8.  
  9. public class MyThreadPool extends ThreadPoolExecutor {  
  10.     private static final int pool_size = 10;  
  11.     private boolean is_paused;  
  12.     private ReentrantLock pause_lock = new ReentrantLock();  
  13.     private Condition unpaused = pause_lock.newCondition();  
  14.       
  15.     public MyThreadPool(){  
  16.        super(pool_size,         // core pool size  
  17. pool_size,          // maximum pool size  
  18. 0L,     // keep-alive time for idle thread  
  19. TimeUnit.SECONDS,   // time unit for keep-alive setting  
  20. new LinkedBlockingQueue<Runnable>(pool_size)); // work queue   
  21.     }  
  22.  
  23.     // some overrides  
  24.     protected void beforeExecute(Thread t, Runnable r) {  
  25.        super.beforeExecute(t, r);  
  26.        pause_lock.lock();  
  27.        try {  
  28.           while (is_paused) unpaused.await();  
  29.        }  
  30.    
  31.        catch (InterruptedException e) { t.interrupt(); }   
  32.        finally { pause_lock.unlock(); }  
  33.     }  
  34.       
  35.     public void pause() {  
  36.        pause_lock.lock();  
  37.        try {  
  38.           is_paused = true;  
  39.        }   
  40.        finally { pause_lock.unlock(); }  
  41.     }  
  42.       
  43.     public void resume() {  
  44.        pause_lock.lock();  
  45.        try {  
  46.           is_paused = false;  
  47.           unpaused.signalAll();  
  48.        }   
  49.        finally { pause_lock.unlock(); }  
  50.     }  

MyThreadPool创建了一个线程数为10的线程池,线程使用固定大小的队列来存储。当使用线程池时,在线程池中有空闲线程被释放出来之前,排队中的下一个任务必须等待。而这些管理的细节都由线程池来自动处理。MyThreadPool重写了ThreadPoolExecutor中的几个方法。

使用MyThreadPool对象,端点发布程序可以支持多线程处理。下面是在前发布程序的基础上修改后的代码,通过不同方法将发布任务分解:

  1. package ch01.ts;  
  2. import javax.xml.ws.Endpoint;  
  3. class TimePublisherMT { // MT for multithreaded  
  4.     private Endpoint endpoint;  
  5.  
  6.     public static void main(String[ ] args) {  
  7.         TimePublisherMT self = new TimePublisherMT();  
  8.         self.create_endpoint();  
  9.         self.configure_endpoint();  
  10.         self.publish();  
  11.     }  
  12.     private void create_endpoint() {  
  13.         endpoint = Endpoint.create(new TimeServerImpl());  
  14.     }  
  15.    
  16.     private void configure_endpoint() {  
  17.         endpoint.setExecutor(new MyThreadPool());  
  18.     }  
  19.     private void publish() {  
  20.         int port = 8888;  
  21.         String url = "http://localhost:" + port + "/ts";  
  22.         endpoint.publish(url);  
  23. System.out.println("Publishing TimeServer on port " + port);  
  24.     }  

ThreadPoolWorker编写完后,剩余的工作就是设置本例中Endpoint实例的executor属性,而发布程序并不会涉及线程管理的任何细节。

多线程端点发布程序比较适合一些轻量级别的产品,但是在真正的应用场景中,上面这个发布程序并不是一个服务容器;服务容器可以在同一个端口发布多个Web服务。一些Web容器,比如Tomcat,提供了这些功能实现,比较适合于在发布多个Web服务时使用。后面例子中的Web服务将会介绍如何通过Tomcat发布。

多线程端点服务发布程序(摘)