简体   繁体   中英

How to execute multiple models in parallel instead of sequentially?

I have various models and I am executing those models one by one sequentially. I will have around 200 models.

Below is my code where I am executing those models one by one

Map<String, List<ServerMetrics>> metricsHolder = new HashMap<String, List<ServerMetrics>>();

for (String alias : serverNames) {
    List<ClientsModel> modelMetadata = getModelAttributes();
    List<MachineInfo> machineInfo = getMachineInfo();

    List<ServerMetrics> metricsList = new ArrayList<ServerMetrics>();

    // calling model one by one sequentially
    // is there any way to make this multithreaded?
    // here modelMetadata size might be 100 or 200
    for (ClientsModel modelList : modelMetadata) {
        String modelValue = modelList.getModelValue();
        String modelId = String.valueOf(modelList.getModelId());

        // execute my model here and storing the metrics in the metricsList object
        ServerMetrics metrics = TestUtils.executeModelMetrics(machineInfo, modelValue);
        metrics.setModelId(modelId);

        metricsList.add(metrics);
    }

    metricsHolder.put(alias, dynMetricsList);
}

Problem Statement:-

Is there any way we can make the model execution multithreaded and then store the result into a metricsList object?

If there are no data race conditions in your code (multi-threaded access to the same data that is not properly synchronized), then you can use a threadpool, in the form of an ExecutorService , to run Callable implementations on threads. You can do the work in the Callable .

On the main thread, the ExecutorService returns a Future that you can then wait for once all the tasks have been spawned.

The size of the thread pool (here set at 10 , but you can change it) determines how many run in parallel. You can still execute more Callable s than the size of the thread pool.

    Map<String, List<ServerMetrics>> metricsHolder = new HashMap<String, List<ServerMetrics>>();
    // Size of thread pool set at 10 - can be increased but increasing it 
    // to more than the number of cores on your computer is probably not 
    // useful, as it seems like your task is CPU-bound
    ExecutorService executorService = Executors.newFixedThreadPool(10);

    for (String alias : serverNames) {
        List<ClientsModel> modelMetadata = getModelAttributes();
        List<MachineInfo> machineInfo = getMachineInfo();

        List<Future<ServerMetrics>> metricsFutureList = new ArrayList<Future<ServerMetrics>>();

        // calling model one by one sequentially
        // is there any way to make this multithreaded?
        for (ClientsModel modelList : modelMetadata) {
            final String modelValue = modelList.getModelValue();
            final String modelId = String.valueOf(modelList.getModelId());

            metricsFutureList.add(executorService.submit(new Callable<ServerMetrics>() {
                @Override
                public ServerMetrics call() throws Exception {

                    // execute my model here and storing the metrics in the list
                    ServerMetrics metrics = TestUtils.executeModelMetrics(machineInfo, modelValue);
                    metrics.setModelId(modelId);
                    return metrics;
                }
            }));

        }
        List<ServerMetrics> metricsList = new ArrayList<ServerMetrics>();
        for (Future<ServerMetrics> future : metricsFutureList) {
            metricsList.add(future.get());
        }
        metricsHolder.put(alias, dynMetricsList);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM