一文弄懂Java线程池 + Runnable多线程 + 调用WebService接口

2023年 9月 24日 51.0k 0

大家好,我是哪吒。

一、需求很简单

根据接口文档,调用第三方webservice接口,拼接入参,处理回参。

RPC调用Webservice接口是一种远程调用的方式,通过指定Webservice接口的调用地址、命名空间、调用的方法名调用远程接口获取结果。

二、解决方案

  • 通过 ExecutorService 新建线程池;
  • 定义thread类,请求webservice接口;
  • 三、线程池简介

    1、创建方式

    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler)
    

    2、核心参数

  • corePoolSize : 核心线程数,一旦创建将不会再释放。如果创建的线程数还没有达到指定的核心线程数量,将会继续创建新的核心线程,直到达到最大核心线程数后,核心线程数将不在增加;如果没有空闲的核心线程,同时又未达到最大线程数,则将继续创建非核心线程;如果核心线程数等于最大线程数,则当核心线程都处于激活状态时,任务将被挂起,等待空闲线程来执行。
  • maximumPoolSize : 最大线程数,允许创建的最大线程数量。如果最大线程数等于核心线程数,则无法创建非核心线程;如果非核心线程处于空闲时,超过设置的空闲时间,则将被回收,释放占用的资源。
  • keepAliveTime : 也就是当线程空闲时,所允许保存的最大时间,超过这个时间,线程将被释放销毁,但只针对于非核心线程。
  • unit : 时间单位,TimeUnit.SECONDS等。
  • workQueue : 任务队列,存储暂时无法执行的任务,等待空闲线程来执行任务。
  • threadFactory : 线程工程,用于创建线程。
  • handler : 当线程边界和队列容量已经达到最大时,用于处理阻塞时的程序。
  • 3、线程池的类型

    (1)单线程池

    只有一个核心线程的线程池,保证任务按FIFO顺序一个个执行。

    ExecutorService singlePool = Executors.newSingleThreadExecutor();
    
    public static ExecutorService newSingleThreadExecutor() {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue()));
        }
    

    (2)固定线程数线程池

    固定数量的可复用的线程数,来执行任务。当线程数达到最大核心线程数,则加入队列等待有空闲线程时再执行。

    我觉得是最常用的线程池。

    Executors.newFixedThreadPool(10);
    
    
    public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue());
        }
    

    (3)可缓存线程池

    创建的都是非核心线程,而且最大线程数为Interge的最大值,空闲线程存活时间是1分钟。
    如果有大量耗时的任务,则不适该创建方式,它只适用于生命周期短的任务。

    ExecutorService cachePool = Executors.newCachedThreadPool();
    
    public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue());
        }
    

    (4)固定线程数,支持定时和周期性任务

    ExecutorService scheduledPool = Executors.newScheduledThreadPool(10);
    
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }
    

    ① scheduleAtFixedRate:

    创建并执行一个在给定初始延迟后的定期操作,也就是将在 initialDelay 后开始执行,然后在initialDelay+period 后下一个任务执行,接着在 initialDelay + 2 * period 后执行,依此类推 ,也就是只在第一次任务执行时有延时。

    public ScheduledFuture scheduleAtFixedRate(Runnable command,
                                                      long initialDelay,
                                                      long period,
                                                      TimeUnit unit);
    

    ② scheduleWithFixedDelay:

    创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟,即总时间是(initialDelay + period)*n。

    public ScheduledFuture scheduleWithFixedDelay(Runnable command,
                                                         long initialDelay,
                                                         long delay,
                                                         TimeUnit unit);
    

    四、webservice

    1、webservice简介

    Web Service也称为web服务,它是一种跨编程语言和操作系统平台的远程调用技术。

    Web Service采用标准的SOAP协议传输(SOAP:Simple Object Access Protocol简单对象访问协议,soap属于w3c标准。并且soap协议是基于http的应用层协议传输xml数据)。

    Web Service采用WSDL作为描述语言,也就是Web Service 的使用说明书。

    W3C为Web Service制定了一套传输数据类型,使用xml进行描述,即XSD(XML Schema Datatypes),任何语言写的web Service 接口在发送数据的时候都要转换成WebService标准的XSD发送。

    2、WebService的三要素

    (1)SOAP

    SOAP也叫做简单对象访问协议,是一种简单的基于xml的协议,它使应用程序通过HTTP来交换数据,可以简单的理解为SOAP= http+xml。

    SOAP协议格式:

  • 必须有Envelope元素,此元素将整个xml文档表示为一条SOAP消息。
  • 可选Header元素,包含头部信息。
  • 必须有Body元素,包含所有的调用和响应信息。
  • 可选的Fault元素,提供有关在处理此消息所发生的错误信息。
  • 在这里插入图片描述

    (2)WSDL

    WSDL是基于XML的用于描述Web Service 及其函数(方法)、参数和返回值。也就是说wsdl是对发布出来的服务中的方法和返回值以及参数的描述(可以成为是WebService的使用说明书)。

    WSDL文档结构,WSDL文档主要包括5个标签:

  • :服务视图,WebService的服务结点,它包括服务端点。
  • :为每个服务端点定义消息格式和协议细节。
  • :服务端点,描述WebService可执行的操作方法,以及相关的消息,通过binding指向portType。
  • :定义一个操作(方法)的数据参数(可有多个参数)
  • :定义WebService使用的全部数据类型。
  • (3)UDDI

    UDDI是一种目录服务,通过它,企业可注册并搜集Web Service。企业将自己提供的Web Service注册在UDDI,也可以使用别的企业在UDDI注册Web Service服务,从而达到资源共享。UDDI旨在将全球的Web Service资源进行共享。

    四、代码实例

    1、封装接口调用工具类 WebServiceUtil

    package com.guor.rpc;
    
    import com.neusoft.basic.threadPool.ThreadPoolFactoryUtil;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.concurrent.ExecutorService;
    
    public class WebServiceUtil {
    
        // 日志
        private static final Logger logger = LoggerFactory.getLogger(WebServiceUtil.class);
    
        public static void sendRequest(RequestInfo requestInfo) {
            ExecutorService executorService = ThreadPoolFactoryUtil.getInstance();
            try {
                WebServiceThread webServiceThread = new WebServiceThread(requestInfo);
                executorService.execute(webServiceThread);
            } catch (Exception e) {
                logger.error("|#WebServiceUtil|#异常: ", e);
            }
        }
    }
    

    2、线程类,请求webservice接口

    package com.guor.rpc;
    
    import com.alibaba.fastjson.JSON;
    import org.apache.axis2.addressing.EndpointReference;
    import org.apache.axis2.client.Options;
    import org.apache.axis2.rpc.client.RPCServiceClient;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    
    import javax.xml.namespace.QName;
    
    public class WebServiceThread implements Runnable {
    
        // 日志
        private static final Logger logger = LoggerFactory.getLogger(WebServiceThread.class);
    
        private RequestInfo requestInfo;
    
        @Value("${webservice.url}")
        private String url;
    
        @Value("${webservice.nameSpace}")
        private String nameSpace;
    
        @Value("${webservice.method}")
        private String method;
    
        public WebServiceThread(RequestInfo requestInfo) {
            this.requestInfo = requestInfo;
        }
    
        @Override
        public void run() {
            try {
                String request = JSON.toJSONString(this.requestInfo);
                // 创建远程调用接口的RPC(RPCServiceClient)对象
                RPCServiceClient serviceClient = new RPCServiceClient();
                // 指定webservice接口地址
                EndpointReference endpointReference = new EndpointReference(url);
                serviceClient.setTargetEPR(endpointReference);
    
                Options options = serviceClient.getOptions();
                // 超时时间30s
                options.setTimeOutInMilliSeconds(30 * 1000);
                // 设置接口的调用地址
                options.setTo(endpointReference);
    
                // 设置命名空间和调用的方法名
                QName opName = new QName(nameSpace, method);
                //设置请求的报文
                Object[] param = new Object[]{request};
                // 返值值类型
                Class[] types = new Class[]{String.class};
                Object[] ret = serviceClient.invokeBlocking(opName, param, types);
                // 返回值逻辑处理
            } catch (Exception e) {
                logger.error("|#WebServiceUtil|#异常: ", e);
            }
        }
    }
    

    3、实体类

    package com.guor.rpc;
    
    import lombok.Data;
    
    @Data
    public class RequestInfo {
    
        private int id;
        private String name;
        private String msg;
    }
    

    4、所需Jar包

    
        org.apache.axis2
        axis2
        1.6.3
        pom
        compile
    
    
        org.apache.axis2
        axis2-adb
        1.6.3
        jar
        compile
    
    
        org.apache.axis2
        axis2-kernel
        1.6.3
        jar
        compile
    
    
        org.apache.axis2
        axis2-transport-http
        1.6.3
    
    
        org.apache.axis2
        axis2-transport-local
        1.6.3
    
    

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论