Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何并行执行多个模型而不是顺序执行?_Java_Multithreading_Thread Safety_Executorservice_Callable - Fatal编程技术网

Java 如何并行执行多个模型而不是顺序执行?

Java 如何并行执行多个模型而不是顺序执行?,java,multithreading,thread-safety,executorservice,callable,Java,Multithreading,Thread Safety,Executorservice,Callable,我有各种各样的模型,我正在按顺序一个接一个地执行这些模型。我将有大约200个模型 下面是我一个接一个地执行这些模型的代码 Map<String, List<ServerMetrics>> metricsHolder = new HashMap<String, List<ServerMetrics>>(); for (String alias : serverNames) { List<ClientsModel> modelMe

我有各种各样的模型,我正在按顺序一个接一个地执行这些模型。我将有大约200个模型

下面是我一个接一个地执行这些模型的代码

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);
}
Map metricshholder=new HashMap();
for(字符串别名:serverNames){
List modelMetadata=getModelAttributes();
List machineInfo=getMachineInfo();
List metricsList=new ArrayList();
//依次调用模型
//有没有办法使这个多线程?
//这里modelMetadata的大小可能是100或200
for(客户端模型列表:模型元数据){
字符串modelValue=modelList.getModelValue();
String modelId=String.valueOf(modelList.getModelId());
//在此处执行我的模型,并将度量存储在metricsList对象中
ServerMetrics=TestUtils.executeModelMetrics(machineInfo,modelValue);
metrics.setModelId(modelId);
metricsList.add(metrics);
}
metricsHolder.put(别名,dynMetricsList);
}
问题陈述:-


我们有没有办法使模型执行多线程化,然后将结果存储到
metricsList
对象中?

如果代码中没有数据竞争条件(对未正确同步的相同数据的多线程访问),那么您可以使用线程池,以
ExecutorService
的形式,在线程上运行
Callable
实现。您可以在
可调用的
中完成这项工作

在主线程上,
ExecutorService
返回一个
Future
,您可以在生成所有任务后等待它

线程池的大小(此处设置为
10
,但您可以更改它)决定有多少线程并行运行。您仍然可以执行比线程池大小更多的
Callable
s

    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);
    }
Map metricshholder=new HashMap();
//线程池的大小设置为10-可以增加,但不能增加
//要超过您计算机上的内核数可能是不可能的
//很有用,因为您的任务似乎受CPU限制
ExecutorService ExecutorService=Executors.newFixedThreadPool(10);
for(字符串别名:serverNames){
List modelMetadata=getModelAttributes();
List machineInfo=getMachineInfo();
List metricsFutureList=新建ArrayList();
//依次调用模型
//有没有办法使这个多线程?
for(客户端模型列表:模型元数据){
最终字符串modelValue=modelList.getModelValue();
最终字符串modelId=String.valueOf(modelList.getModelId());
metricsFutureList.add(executorService.submit)(新的可调用(){
@凌驾
public ServerMetrics调用()引发异常{
//在此处执行我的模型并将度量存储在列表中
ServerMetrics=TestUtils.executeModelMetrics(machineInfo,modelValue);
metrics.setModelId(modelId);
回报指标;
}
}));
}
List metricsList=new ArrayList();
for(未来:metricsFutureList){
metricsList.add(future.get());
}
metricsHolder.put(别名,dynMetricsList);
}

如果执行不是相互依赖的,您可以为每个线程生成一个新线程,然后存储结果。你不能吗?如果我有大约200个模型,那么你想让我产生200个线程吗?谢谢你的建议。在您的第一行中,您提到了关于
如果没有数据竞争条件,根据您的理解,我的代码中会出现什么问题?如果模型使用相同的数据(至少有一个
executeModelMetrics
方法更新了至少一个其他
executeModelMetrics
读取的数据),然后,您需要开始考虑多线程同步方法。如果对
executeModelMetrics
的多次调用在完全不同的Java对象上工作,或者它们没有修改Java对象(如果在线程启动之前已经设置了所有值也没关系),那么您就没有问题了。@ErwinBolwidt在我的例子中是,
executeModelMetrics
在不同的Java对象上工作,它们不会修改Java对象,所以应该可以。但他需要同步对其
metricsHolder
的访问;它有被多个线程上的
put()
损坏的危险。这使它更加安全:
Map metricshholder=Collections.synchronizedMap(new HashMap())
@gknicker不太可能,因为
metricshholder
不能在多个线程中访问(仅在主线程中)