Поток Java не изменяет статическое значение

Я реализовал следующий класс кода:

public class sumThread implements Runnable {
    private int index;

    private static int sum = 0;

    public sumThread(int index) {
        this.index = index;
    }

    public static int getSum() {
        return sum;
    }

    @Override
    public void run() {
        for (int i = 0; i < index + 100; i++) {
            sum += i;
        }
    }
}

2 класс:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SigRuntime {

    public static void main(String args[]) {
        ExecutorService es = Executors.newCachedThreadPool();
        int index = 0;
        // for (int i = 0; i < 10; i++) {
        sumThread t = new sumThread(index);
        index += 100;
        es.execute(t);
        // }
        System.out.println(sumThread.getSum());
    }}

Я пытаюсь произвести суммирование от 0 до 100, используя 10 потоков, поскольку каждый принимает 100 значений

Когда я использую sumThread.getSum (), я получаю 0 как возвращаемое значение! Что с этим не так?

Пожалуйста, придерживайтесь соглашений об именах. Имена классов PascalCase.

Zabuzard 22.06.2018 22:51

Вы уверены, что es.execute (t); Работа? Насколько мне известно, вы можете начать обсуждение с помощью .start ();

KunLun 22.06.2018 22:52

@ Athl1n3 Обратите внимание, что ваша переменная sum - это общая переменная, которая изменяется всеми потоками, она должна быть volatile. Также обратите внимание, что += - это операция нет, операция атомный. Это означает, что вы потеряете часть приращений, поскольку не защитите его. Используйте AtomicInteger или синхронизируйте приращение.

Zabuzard 22.06.2018 22:53

es инициализируется следующим образом ExecutorService es = Executors.newCachedThreadPool (); этот метод можно найти в книге Java How to Programming, Harvey Deitel, глава 23.

Adam Ma 22.06.2018 22:54

@Zabuza Я пробовал выполнить только 1 поток, но он все равно дает 0

Adam Ma 22.06.2018 22:57

@ Athl1n3 Покажите полный код, создайте минимальный воспроизводимый пример (акцент на полный). Я уверен, что это связано с двумя вещами, которые я только что упомянул (или вы забыли запустить потоки).

Zabuzard 22.06.2018 22:58

Мне любопытно, почему вы хотите, чтобы эта переменная была статической.

KunLun 22.06.2018 22:59

@ raul1ro Я хочу суммировать весь результат потоков, суммы первого потока 0-99, 2nd100-199, 200-299 ...

Adam Ma 22.06.2018 23:04

@Zabuza отредактировал тему, добавлен полный код

Adam Ma 22.06.2018 23:08

Как вы думаете, что делает es.execute(t)? А почему ты так думаешь? Javadoc говорит: Выполняет заданную команду в когда-нибудь в будущем. --- Когда вы сразу вызываете System.out.println(sumThread.getSum());, метод run() еще даже не был вызван.

Andreas 22.06.2018 23:09
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
10
108
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

метод sumThread.getSum(); выполняется до инициализации потока

если вы добавите

@Override
    public void run() {
        for (int i = 0; i < index + 100; i++) {
            sum += i;
        }
        System.out.println(sumThread.getSum()); //check the sum
    }

вы сможете увидеть итоговый результат.

когда вы создаете поток, приложение продолжает линейное выполнение, а затем выполняет поток, когда решает случайный алгоритм.

Боже, не думаю, что я это пропустил! похоже пора спать

Adam Ma 22.06.2018 23:14

Есть ли возможное ожидание, чтобы заставить программу ждать, пока весь поток не будет выполнен с использованием ExecutorService?

Adam Ma 22.06.2018 23:15

P.S: нашел, вы можете использовать es.awaitTermination (1, TimeUnit.MINUTES), чтобы он дал всем потокам минуту для завершения

Adam Ma 22.06.2018 23:18

после создания потока приложение будет продолжать работать очень быстро, вы можете на мгновение остановить его, используя Thread.sleep, или создать другой поток, поместить туда печать и принять во внимание, что переменная должна быть изменчивой.

Jorge L. Morla 22.06.2018 23:29

Вы не рассмотрели здесь проблемы видимости или атомарности: нет гарантии, что потоки увидят самое последнее значение sum, и что потоки не будут мешать при обновлении sum (поскольку += - это две отдельные операции). Самый простой способ исправить оба - превратить sum в AtomicInteger.

Andy Turner 23.06.2018 01:17

Другие вопросы по теме