如何使用自己的线程池和其他配置独立运行两个进程?

时间:2016-11-27 18:25:32

标签: java multithreading oop

我有两个processes,如下面的列表所示。

public static final ImmutableList<String> processes = ImmutableList.of("processA", "processB");

现在对于每个process,我有一个不同的Properties对象,这两个进程之间根本没有关系和依赖关系。它们彼此独立。

我编写的代码现在只使用一个进程,我需要有效地扩展我的设计,以便它可以用于两个进程。每个进程都应该拥有自己的线程池配置。例如,我可能希望运行带有三个线程的processA和带有两个线程的processB

public class ProcessA implements Runnable {
  private final Properties props;
  private final String processName;

  public ProcessA(String processName, Properties props) {
    this.processName = processName;
    this.props = props;
  }

  @Override
  public void run() {
    List<String> clients = getClients(processName);
    try {
      // .. some code here which does  processing
      // calling some classes here as well

    } catch (Exception ex) {
      // log error
    } finally {
      // close processA here
    }
  }

  public void shutdown() {
    // shutdown processA here
  }
}

以下是我执行processA的主要课程。一般来说,我将仅从类下面执行我的两个过程。

@Singleton
@DependencyInjectionInitializer
public class Initializer {
  private final ExecutorService executorServiceProcessA = Executors.newFixedThreadPool(3);
  private final List<ProcessA> processAList = new ArrayList<>();

  public Initializer() {
    logger.logInfo("initializing here called.");
    TestUtils.getInstance().initializeData();
  }  

  // this is the entrance point for my code
  @PostConstruct
  public void postInit() {
    for (int i = 0; i < 3; i++) {
        ProcessA process =
            new ProcessA("processA", properties);
        processAList.add(process);
        executorServiceProcessA.submit(process);         
    }       
  }

  @PreDestroy
  public void shutdown() {
    Runtime.getRuntime().addShutdownHook(new Thread() {
      @Override
      public void run() {
        for (ProcessA process : processAList) {
          process.shutdown();
        }
        executorServiceProcessA.shutdown();
        try {
          executorServiceProcessA.awaitTermination(1000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException ex) {
          Thread.currentThread().interrupt();
        }
      }
    });
  }
}

我将只有一个Initializer类,它将从postInit方法执行我的流程,然后从shutdown方法关闭该流程。

问题陈述: -

现在我如何扩展我的设计,以便它可以有效地使用两个processes?每个进程都应该有自己的线程池,它自己的属性对象,我应该能够从postInit方法执行它们,然后从shutdown方法关闭。

最好和最有效的方法是什么?

1 个答案:

答案 0 :(得分:1)

您的代码中存在明显的违反DRY(不要重复自己)原则

换句话说,你的ProcessMain类中有很多Boilerplate代码,可以通过使用抽象类来消除(或者如果你使用的话使用接口带有default方法的Java8。)

所以我创建了两个ProcessProcessHandler抽象类来重用代码,这些代码在每个进程和进程处理中都很常见。 现在,您可以定义扩展Process的ProcessAProcessB类以及扩展ProcessHandler类的ProcessHandlerAProcesshandlerB

关键点是此解决方案可以扩展到任意数量的Process **,即,这遵循OOP的开放/封闭原则

您可以参考以下代码并注释:

流程类(摘要):

public abstract Process implements Runnable {

        private final Properties props;
        private final String processName;

        public Process(String processName, Properties props) {
            this.processName = processName;
            this.props = props;
        }

        //this can also be a non abstract (reusable) method 
        // to eliminate boiler plate code (if any)
        public abstract void shutdown();
    }

ProcessA课程:

public class ProcessA extends Process {

          public ProcessA(String processName, Properties props) {
              super(processName, props);
          }

          @Override
          public void run() {
              //add run code here
          }

          @Override
          public void shutdown() {
              //shut down code
          }
    }

流程B类:

//与ProcessA类似,其中包含B

的具体细节

ProcessHandler类(摘要):

public abstract class ProcessHandler {

         private final ExecutorService executorServiceProcess;
         private final List<Process> processList;
         private int poolSize;

         protected ProcessHandler(int poolSize) {
             executorServiceProcess = Executors.newFixedThreadPool(poolSize);
             processList = new ArrayList<>();
             this.poolSize = poolSize;
         }

          public void postInit(Process process) {
             for (int i = 0; i < poolSize; i++) {
                    processList.add(process);
                    executorServiceProcess.submit(process);    
              }  
          }

         public void shutdown() {
                Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    for (Process process : processList) {
                      process.shutdown();
                    }
                    executorServiceProcess.shutdown();
                    try {
                      executorServiceProcess.
                        awaitTermination(1000, TimeUnit.MILLISECONDS);
                    } catch (InterruptedException ex) {
                      Thread.currentThread().interrupt();
                    }
                  }
                });
         }
 }

ProcessHandlerA类:

public class ProcessHandlerA extends ProcessHandler {

          public ProcessHandlerA() {
              super(3);//configure pool size properly w.r.to ProcessA requirements
          }

          public void postInit() {
              ProcessA processA = new ProcessA("processA", properties);
              super(processA);
          }

          public void shutdown() {
              super.shutdown();
          }
     }

ProcessHandlerB类:

//与ProcessHandlerA类似,包含B

的具体细节