zoukankan      html  css  js  c++  java
  • 使用线程池执行多线程完毕后的操作

    场景:在使用线程池执行多线程之后,获取每个线程获取的数据或是结果的集合,那么在主线程中想要获取完整的集合,就要等子线程执行完毕后,才能获取;

    目的:实现子线程执行完毕,再执行子线程;

    两种方法:第一种:

    ExecutorService executorService = PingVMThreadPool.getInstance().getExecutorService();

    //根据list获取具体虚拟机的ip,
    for (int i = 0; i < listFromPage.size(); i++) {
    PingVMDeploy engine = null;
    engine = new PingVMDeploy(listFromPage.get(i).toString());
    //线程池提交线程
    executorService.submit(engine);
    }
    //关闭线程池
    executorService.shutdown();

    while(true){
    if(executorService.isTerminated()){判断是否线程关闭
    System.out.println("线程结束");
    break;
    }
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //在线程关闭之后去获取完整的list集合,否则获取的不完整
    ArrayList listFromVM = PingVMDeploy.printList();

    这个listFromVM集合是根据子线程中的run方法返回的,具体见下面:


     @Override
    public void run() {
    //这里循环的应该是ip
    boolean flag = MyPing.isOk(ip);
    if(flag){
    arrayList.add(ip);
    System.out.println(ip+",,,");
    }
    }

    //获取所有的arraylist
    public static ArrayList printList(){
    return arrayList;
    }

    这样我们需要获取的list集合就能完整的获取到,但是这是一次性的,也就是说,这个shutdown执行完毕之后,这个线程池就不能再使用了 ,再次使用的时候,就会出现下面的问题:

    再次使用就会报错:

    java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@4a85a05 rejected from java.util.concurrent.ThreadPoolExecutor@50848921[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 15]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
    at com.cloudmap.csmc.kernel.cloud.svm.service.SVMRegistService.saveInitsvmAdd(SVMRegistService.java:286)
    at com.cloudmap.csmc.kernel.cloud.svm.controller.SVMRegistController.saveInitsvmAdd(SVMRegistController.java:172)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.nutz.mvc.impl.processor.MethodInvokeProcessor.process(MethodInvokeProcessor.java:22)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at com.cloudmap.csmc.kernel.AccessControlProcessor.process(SourceFile:141)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at com.cloudmap.csmc.kernel.logging.LoggingProcessor.process(SourceFile:71)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.AdaptorProcessor.process(AdaptorProcessor.java:33)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.ActionFiltersProcessor.process(ActionFiltersProcessor.java:40)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.ModuleProcessor.process(ModuleProcessor.java:85)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.EncodingProcessor.process(EncodingProcessor.java:27)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor.process(UpdateRequestAttributesProcessor.java:15)
    at org.nutz.mvc.impl.NutActionChain.doChain(NutActionChain.java:40)
    at org.nutz.mvc.impl.ActionInvoker.invoke(ActionInvoker.java:64)
    at org.nutz.mvc.ActionHandler.handle(ActionHandler.java:31)
    at org.nutz.mvc.NutFilter.doFilter(NutFilter.java:101)
    at com.cloudmap.csmc.CMNutFilter.doFilter(SourceFile:70)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:660)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:808)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

    这是什么原因?

    因为在第一次使用了线程池之后,他就被shutdown了,所以再次调用线程的时候,就会报出这个异常,(报出这个异常有俩原因,可以参考这篇文章 https://blog.csdn.net/zinss26914/article/details/38922449

    所以呢,怎么解决?

    第一种思路:每次调用,重新new一个线程池

    第二种思路:也就是第二种方法,

    第二种方法:(不关闭线程池,就是每次子线程执行完毕后都会有一个返回值,这样线程池就不必关闭)

    继承callabale:

    public class PingVMDeploy2 implements Callable {

    private String ip;

    public PingVMDeploy2() {
    }

    public PingVMDeploy2(String ip) {
    this.ip = ip;
    }

    public String getIp() {
    return ip;
    }

    public void setIp(String ip) {
    this.ip = ip;
    }

    @Override
    public Object call() throws Exception {
    //这里循环的应该是ip
    boolean flag = MyPing.isOk(ip);
    if(flag){
    return ip;
    }
    return "1";
    }
    }


    主线程:
    ArrayList listFromVM = new ArrayList();

    for (int i = 0; i < listFromPage.size(); i++) {
    PingVMDeploy2 engine = null;
    engine = new PingVMDeploy2(listFromPage.get(i).toString());
    Future submit = executorService.submit(engine);

    try {
    if(!submit.get().equals("1")){
    listFromVM.add(submit.get());
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    这样就可以线程池不shutdown的时候获取返回数据;

    我不是来改变世界的
  • 相关阅读:
    .NET体系结构
    命名空间和程序集
    网站不加www和.com 也能访问的设置
    如何从本机直接复制粘贴文件到服务器
    无法访问已释放的对象。 对象名:“System.ServiceModel.Channels.HttpChannelFactory+HttpRequestChannel”。
    silverlight 数据库更新,UI控件同步更新
    Apache Solr使用自定义QParser后同义词扩展及Token去重的感悟
    Apache Nutch 1.3 学习笔记十(插件机制分析)
    Apache Nutch 1.3 学习笔记十(Ntuch 插件机制简单介绍)
    Apache Nutch 1.3 学习笔记八(LinkDb)
  • 原文地址:https://www.cnblogs.com/notchangeworld/p/11365643.html
Copyright © 2011-2022 走看看