Java各个子模块之间分步骤执行

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Coder__CS/article/details/86554894

在我的业务需求中,需要整合多个任务模块,然后在每个任务模块之间是依赖关系,前者执行完,才能执行后面的任务模块。

对于这样多任务,而且后端处理时间较长的处理逻辑,我的处理方案是,通过多线程的方式将任务加入到线程池中,然后主线程能够直接返回结果给前端,而每个功能模块的直接结果持久化到数据库中,前端的任务结果进度展示,通过轮询查看数据库中的记录情况来呈现。

下面是我制作的一个业务处理模型,在主线程入口处,创建一个Single线程池,能够保证这个线程池中的任务是FIFO,以队列进入顺序进行执行,这个而且这个线程池是没有被阻塞的,因此当所有任务进入该线程池队列中后,主线程就可以直接返回结果;然后各个任务模块被多线程分别调度执行。


下面给出简单模型及Demo代码:

在任务队列中,任务0是第一个队列,需要首先执行,然后子线程阻塞,等待任务0执行结束;随后任务1和任务2同时执行,子线程依然阻塞等待这两个任务执行结束;最后再执行任务3。 

请求层

 http://localhost:8080/deploy/autodeploy/threadPool

View层

 /**
   * [4] 多线程测试
   */
  @RequestMapping("/autodeploy/threadPool")
  public void threadPool(HttpServletRequest request, HttpServletResponse response) {
    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/json; charset=utf-8");

    ResultVo resultVo = new ResultVo();
    resultVo.setCode(1);
    ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
    singleThreadExecutor.execute(new Runnable() {
      @Override
      public void run() {
        autoDeployService.threadPool1(10);
      }
    });

    singleThreadExecutor.execute(new Runnable() {
      @Override
      public void run() {
        autoDeployService.threadPool2(10);
      }
    });

    singleThreadExecutor.execute(new Runnable() {
      @Override
      public void run() {
        autoDeployService.threadPool3(10);
      }
    });

    try {
      response.getWriter().write(JsonUtil.getJson(resultVo));
      response.getWriter().close();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

  }

Service层 

public class AutoDeployService extends BaseService {

  private Logger logger = LoggerFactory.getLogger(ServerController.class.getName());

  /**
   * 测试 线程池1
   */
  public void threadPool1(int count) {
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    final CountDownLatch latch = new CountDownLatch(count);
    logger.info("   线程池0   -   正在执行...");
    for (int i = 0; i < count; i++) {
      final int index = i;
      executorService.execute(new Runnable() {
        @Override
        public void run() {
          try {
            logger.info("线程池0 - " + index);
            Thread.sleep(2000);
            latch.countDown();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      });
    }
    // wait
    try {
      latch.await();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }


  /**
   * 测试 线程池2
   */
  public void threadPool2(int count) {
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    final CountDownLatch latch = new CountDownLatch(count);
    logger.info("   线程池1/2   -   正在执行...");
    for (int i = 0; i < count; i++) {
      final int index = i;
      executorService.execute(new Runnable() {
        @Override
        public void run() {
          try {
            logger.info("线程池1 - " + index);
            logger.info("线程池2 - " + index);
            Thread.sleep(1000);
            latch.countDown();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      });
    }

    // wait
    try {
      latch.await();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  /**
   * 测试 线程池3
   */
  public void threadPool3(int count) {
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    CountDownLatch latch = new CountDownLatch(count);
    logger.info("   线程池3   -   正在执行...");
    for (int i = 0; i < count; i++) {
      final int index = i;
      executorService.execute(new Runnable() {
        @Override
        public void run() {
          try {
            logger.info("线程池3 - " + index);
            Thread.sleep(3000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      });
    }
    // wait
    try {
      latch.await();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

控制台输出结果 

19:28:52.411 [pool-14-thread-1] INFO  com.nkm.deploy.view.ServerController -    线程池0   -   正在执行...
19:28:52.413 [pool-15-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 0
19:28:52.413 [pool-15-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 1
19:28:52.414 [pool-15-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 2
19:28:54.414 [pool-15-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 4
19:28:54.414 [pool-15-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 5
19:28:54.414 [pool-15-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 3
19:28:56.414 [pool-15-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 6
19:28:56.414 [pool-15-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 7
19:28:56.414 [pool-15-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 8
19:28:58.414 [pool-15-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池0 - 9
19:29:00.414 [pool-14-thread-1] INFO  com.nkm.deploy.view.ServerController -    线程池1/2   -   正在执行...
19:29:00.415 [pool-16-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 0
19:29:00.415 [pool-16-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 0
19:29:00.415 [pool-16-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 1
19:29:00.415 [pool-16-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 1
19:29:00.415 [pool-16-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 2
19:29:00.415 [pool-16-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 2
19:29:01.416 [pool-16-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 3
19:29:01.416 [pool-16-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 5
19:29:01.416 [pool-16-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 4
19:29:01.416 [pool-16-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 3
19:29:01.416 [pool-16-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 5
19:29:01.416 [pool-16-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 4
19:29:02.416 [pool-16-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 8
19:29:02.416 [pool-16-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 7
19:29:02.416 [pool-16-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 6
19:29:02.416 [pool-16-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 8
19:29:02.416 [pool-16-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 7
19:29:02.416 [pool-16-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 6
19:29:03.416 [pool-16-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池1 - 9
19:29:03.416 [pool-16-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池2 - 9
19:29:04.416 [pool-14-thread-1] INFO  com.nkm.deploy.view.ServerController -    线程池3   -   正在执行...
19:29:04.417 [pool-17-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 0
19:29:04.417 [pool-17-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 1
19:29:04.417 [pool-17-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 2
19:29:07.417 [pool-17-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 3
19:29:07.417 [pool-17-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 4
19:29:07.417 [pool-17-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 5
19:29:10.417 [pool-17-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 7
19:29:10.417 [pool-17-thread-2] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 8
19:29:10.417 [pool-17-thread-1] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 6
19:29:13.417 [pool-17-thread-3] INFO  com.nkm.deploy.view.ServerController - 线程池3 - 9

前端请求调用的返回结果,这个结果在请求发送到后端,在后端业务逻辑还没有执行完,就马上返回到前端,因为执行的主线程是不存在阻塞的,只有子线程才有阻塞。

{
    "code": 1
}

 

展开阅读全文

没有更多推荐了,返回首页