Java Многопоточность: Создать новую карту с другим потоком - PullRequest
0 голосов
/ 13 июля 2020

Некоторое время я использую многопоточность. Мне нужна помощь в следующем сценарии. У меня есть список предметов. Я хочу выполнить метод для каждого элемента списка и сохранить разные результаты для каждого элемента списка на карте, где ключ будет элементом, а значение будет результатом.

public class RecordData {
    public static void main(String[] args) throws InterruptedException {
        List<String> names = new ArrayList<>();
        names.add("Krish");
        names.add("harry");
        names.add("Rin");

        DataGenerator generator = new DataGenerator(
                Executors.newFixedThreadPool(3));

        names.forEach(t -> generator.start(t));
        Thread.sleep(Duration.ofSeconds(2).toMillis());

        generator.stop();
        ConcurrentHashMap<String, DataGenerator.Result> resultMap = generator.getResultMap();
        System.out.println("resultMap");
    }
}


public class DataGenerator {

        private final ExecutorService executor;
        private final Random random;
        private List<String> request;
        private ConcurrentHashMap<UsageConsumed, Double> usageMap ;

    private ConcurrentHashMap<String, Result> resultMap= new ConcurrentHashMap<>();

        // Used to signal a graceful shutdown
        private volatile boolean stop = false;


        public DataGenerator(ExecutorService executor) {
            this.executor = executor;
            this.random = new Random();
        }

        public void start(String name) {
            Runnable generator = () -> {
                successfulRequest = new ArrayList<>();
                usageMap= new ConcurrentHashMap<>();
                usageMap.put(UsageConsumed.Write, 0.0);
                usageMap.put(UsageConsumed.Read, 0.0);
                try {
                    while (!stop) {
                        // my logic
                        //getData(status, productname, read, write);

                    }
                    Map<String, Long> successfulRequestLatencyMap;

                    synchronized(successfulRequest) {
                        successfulRequestLatencyMap = successfulRequest.stream().collect(Collectors.
                                groupingBy(e -> e, Collectors.counting()));
                    }


                   Result result = new Result(usageMap,
                            successfulRequestLatencyMap);

                    resultMap.put(name, result);
                } catch (Exception e) {
                    throw e;
                }
            };
            executor.execute(generator);
        }

        public void stop() {
            // Signal our thread to stop
            stop = true;

            // The shutdown the executor (after waiting a bit to be nice)
            try {
                executor.awaitTermination(1000, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                // Purposely ignore any InterruptedException
                Thread.currentThread().interrupt();
            }
            executor.shutdownNow();
        }

        private void getData(int status, String productname, Double read,
                                           Double write) {
            if (status == 200) {
                request.add(productname);
            }
            usageMap.put(UsageConsumed.Read, usageMap.get(UsageConsumed.Read)+ read);
            usageMap.put(UsageConsumed.Write, usageMap.get(UsageConsumed.Write)+ write);
        }


    public ConcurrentHashMap<String, Result> getResultMap() {
        return resultMap;
    }



    public enum UsageConsumed {
        Read,
        Write
    }


    public class Result {
        private ConcurrentHashMap<UsageConsumed, Double> usageMap;
        private Map<String, Long> successfulRequestMap;
        public Result(ConcurrentHashMap<UsageConsumed, Double> usageMap,
                      Map<String, Long> RequestMap) {
            this.usageMap = usageMap;
            this.successfulRequestMap = RequestMap;
        }
    }

}

Я возникла проблема: я получаю одинаковый результат для usageMap и successRequestMap для каждого элемента списка, хотя значения должны быть разными. Результат, который я получаю с помощью приведенного выше кода, является результатом, объединенным для всех трех элементов. Нужна помощь, как получить правильный результат.

1 Ответ

1 голос
/ 13 июля 2020

Вы должны сделать usageMap локальным в start() и передать его как параметр в getData().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...