viperz
@viperz
inspired by Java

Многопоточность не завершается?

Данный код зависает, есть поменять значение totalCountSpeeches на 2000 - завершается.
У меня есть несколько предположений, но они лишь догадки, поскольку не хватает знаний как работает JVM с несколькими потоками...

public class Solution {
    public static int totalCountSpeeches = 200;
    public static int soundsInOneSpeech = 1000000;

    public static void main(String[] args) throws InterruptedException {
        Politic ivanov = new Politic("Иванов");
        Politic petrov = new Politic("Петров");
        Politic sidorov = new Politic("Сидоров");

        while (ivanov.getCountSpeaches() + petrov.getCountSpeaches() + sidorov.getCountSpeaches() < totalCountSpeeches) {
        }

        System.out.println(ivanov);
        System.out.println(petrov);
        System.out.println(sidorov);
    }

    public static class Politic extends Thread {
        private int countSounds;

        public Politic(String name) {
            super(name);
            start();
        }

        public void run() {
            while (countSounds < totalCountSpeeches * soundsInOneSpeech) {
                countSounds++;
            }
        }

        public int getCountSpeaches() {
            return countSounds / soundsInOneSpeech;
        }

        @Override
        public String toString() {
            return String.format("%s сказал речь %d раз", getName(), getCountSpeaches());
        }
    }
}
  • Вопрос задан
  • 249 просмотров
Решения вопроса 1
@pbahushevich
Runnable картины не изменит.
Во-первых комментарии по коду
while (ivanov.getCountSpeaches() + petrov.getCountSpeaches() + sidorov.getCountSpeaches() < totalCountSpeeches) {
        }

тут я так понимаю ты ждешь когда все вместе наберут 200 голосов и после этого цикл прекратится и у тебя будут данные о том кто сколько голосов набрал.
Проблема в том что конец цикла происходит в потоке main, а остальные потоки никак об этом не знают и продолжат работать. И между окончанием цикла и выводом результатов на экран 3 потока успеют много чего сделать и результаты уже будут сильно отличаться. Ну или не сильно ))) т.е. сумма ровно в 200 не сойдется.
Проблема еще в том что у тебя зависает еще до выхода из цикла и проблема эта решается в строке
private int countSounds;
добавлением волшебного слова volatile.
почему - см. Java Memory Model либо если не поймешь пиши в комменты ))
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@protven
Ну а почему вы считаете что у вас "зависло" ? Добавьте отладочную печать, увидите, делает что-то ваш код или нет. Проблем то много может быть, начиная от гонки ресурсов и переполнения инта например.

while (countSounds < totalCountSpeeches * soundsInOneSpeech) {
                countSounds++;
                 System.out.println("name -> " + this.getName() + ", " + "count -> " + countSounds);
            }
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы