Я реализовал следующий класс кода:
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 как возвращаемое значение! Что с этим не так?
Вы уверены, что es.execute (t); Работа? Насколько мне известно, вы можете начать обсуждение с помощью .start ();
@ Athl1n3 Обратите внимание, что ваша переменная sum - это общая переменная, которая изменяется всеми потоками, она должна быть volatile. Также обратите внимание, что += - это операция нет, операция атомный. Это означает, что вы потеряете часть приращений, поскольку не защитите его. Используйте AtomicInteger или синхронизируйте приращение.
es инициализируется следующим образом ExecutorService es = Executors.newCachedThreadPool (); этот метод можно найти в книге Java How to Programming, Harvey Deitel, глава 23.
@Zabuza Я пробовал выполнить только 1 поток, но он все равно дает 0
@ Athl1n3 Покажите полный код, создайте минимальный воспроизводимый пример (акцент на полный). Я уверен, что это связано с двумя вещами, которые я только что упомянул (или вы забыли запустить потоки).
Мне любопытно, почему вы хотите, чтобы эта переменная была статической.
@ raul1ro Я хочу суммировать весь результат потоков, суммы первого потока 0-99, 2nd100-199, 200-299 ...
@Zabuza отредактировал тему, добавлен полный код
Как вы думаете, что делает es.execute(t)? А почему ты так думаешь? Javadoc говорит: Выполняет заданную команду в когда-нибудь в будущем. --- Когда вы сразу вызываете System.out.println(sumThread.getSum());, метод run() еще даже не был вызван.




метод sumThread.getSum(); выполняется до инициализации потока
если вы добавите
@Override
public void run() {
for (int i = 0; i < index + 100; i++) {
sum += i;
}
System.out.println(sumThread.getSum()); //check the sum
}
вы сможете увидеть итоговый результат.
когда вы создаете поток, приложение продолжает линейное выполнение, а затем выполняет поток, когда решает случайный алгоритм.
Боже, не думаю, что я это пропустил! похоже пора спать
Есть ли возможное ожидание, чтобы заставить программу ждать, пока весь поток не будет выполнен с использованием ExecutorService?
P.S: нашел, вы можете использовать es.awaitTermination (1, TimeUnit.MINUTES), чтобы он дал всем потокам минуту для завершения
после создания потока приложение будет продолжать работать очень быстро, вы можете на мгновение остановить его, используя Thread.sleep, или создать другой поток, поместить туда печать и принять во внимание, что переменная должна быть изменчивой.
Вы не рассмотрели здесь проблемы видимости или атомарности: нет гарантии, что потоки увидят самое последнее значение sum, и что потоки не будут мешать при обновлении sum (поскольку += - это две отдельные операции). Самый простой способ исправить оба - превратить sum в AtomicInteger.
Пожалуйста, придерживайтесь соглашений об именах. Имена классов PascalCase.