0 / 0 / 0
Регистрация: 02.12.2015
Сообщений: 16
1

Потоки работают с разной скоростью

01.02.2017, 18:00. Показов 1748. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Person extends Thread{
 
    private boolean isCancel = false;
    private int count = 0;
    
    
    public Person (String name){
        super (name);
    }
    
    public void cancel(){
        isCancel = true;
    }
    
    public int getCount(){
        return count;
    }
    
    @Override
    public void run(){
        
        while (!isCancel){
            
            // synchronized(this){        
                count++;
            //}
            try {
                Thread.sleep(35);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println(this.getName() + " прекрастил работу!");
    }
}
 
 
    public static void main(String[] args) throws InterruptedException {
        
        
        Person person1 = new Person("Вася");
        Person person2 = new Person("Петя");
        
            person1.start();
        person2.start();
        
        Thread.sleep(2000);
        person1.cancel();
        person2.cancel();
        
        System.out.println(person1.getName() + " посчитал столько: " + person1.getCount());
        System.out.println(person2.getName() + " посчитал столько: " + person2.getCount());
    }
При выводе результат подсчитанный peson1 и person2 одинаковый (т.е значение переменной count), на 25 попытке теста объект person1 подсчитал меньше на 1 чем объект person2 (блока synchronized не было) хотя этого не должно происходить так как объекты являются экземлярами класса и у них нет общего ресурса... Вопрос почему так происходит? и нужно переменную count оборачивать в блок synchronized? (если да, поясните пожалуйста почему ,буду благодарен)
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.02.2017, 18:00
Ответы с готовыми решениями:

Как работают потоки
Здравствуйте! Объясните мне каким образом работают потоки. Правда ли что они могут ОДНОВРЕМЕННО...

Неправильно работают потоки Java
Здравствуйте, уважаемые форумчане! Не могли бы вы мне объяснить в чем дело... Добавлено через...

Многопоточность. Потоки работают не в том порядке
Здравствуйте, сейчас изучаю многопоточность в джаве и не могу понять, почему package...

Поезд ехал t1 ч со скоростью v1 км / ч, t2 ч со скоростью v2 и t3 ч со скоростью v3. Определить пройденные пути с разной
Поезд ехал t1 ч со скоростью v1 км / ч, t2 ч со скоростью v2 и t3 ч со скоростью v3. Определить...

8
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
01.02.2017, 18:51 2
Если уменьшать паузу Thread.sleep(35), то расхождения будут чаще и больше. Причин расхождений несколько:
- Потоки стартуют не одновременно в неопределенное время
- Каждому потоку выделяется разное количество времени
synchonized тут не поможет. Опиши в чем конкретно задача заключается.
1
345 / 141 / 51
Регистрация: 02.12.2015
Сообщений: 333
01.02.2017, 18:58 3
Потоки не обязаны работать с одинаковой скоростью. Тем более они запускаются и останавливаются не одновременно. Т.е. сам по себе разный результат абсолютно нормален.

Но я вижу две проблемы с многопоточностью:

после cancel поле count читается из главного потока (когда запущенные потоки ещё не остановлены) и в принципе главный поток может прочитать старое значение count. Стоит в главном потоке дождаться завершения двух порождённых (использовать join).

Что касается поля isCancel - тоже оно меняется из одного потока, а читается из другого. И порождённые потоки могут вообще не увидеть что поле изменилась. Нужно объявить это поле как volatile.
0
0 / 0 / 0
Регистрация: 02.12.2015
Сообщений: 16
01.02.2017, 19:49  [ТС] 4
Цитата Сообщение от Lumber Посмотреть сообщение
Что касается поля isCancel - тоже оно меняется из одного потока, а читается из другого.
Каким это образом оно будет видно другому потоку переменная count не статик же! И следовательно оная не является общим ресурсом! Может я не так что-то понимаю...

Добавлено через 3 минуты
Цитата Сообщение от KuKu Посмотреть сообщение
Опиши в чем конкретно задача заключается.
Задача понять когда нужно использовать synchronized написал пример... и проверяю его работу... Т.е в данном случае т.к поле count не является общим ресурсом скажем так то следовательно объекты не имеют к нему общего доступа и тогда synchronized использовать не нужно, верно?
0
345 / 141 / 51
Регистрация: 02.12.2015
Сообщений: 333
01.02.2017, 19:54 5
Лучший ответ Сообщение было отмечено VirtusF12 как решение

Решение

Цитата Сообщение от VirtusF12 Посмотреть сообщение
Каким это образом оно будет видно другому потоку переменная count не статик же!
Она меняется из главного потока при вызове person1.cancel();
И читается из порождённого потока: while (!isCancel)

А count меняется при увеличении в порождённом потоке,
а потом читается в главном когда выводится на экран.
1
0 / 0 / 0
Регистрация: 02.12.2015
Сообщений: 16
01.02.2017, 20:00  [ТС] 6
Цитата Сообщение от Lumber Посмотреть сообщение
И порождённые потоки могут вообще не увидеть что поле изменилась. Нужно объявить это поле как volatile.
И как же поражденные потоки могут не увидеть, когда поток останавливается?
0
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
01.02.2017, 20:03 7
Цитата Сообщение от VirtusF12 Посмотреть сообщение
тогда synchronized использовать не нужно
Объяснять ненужность само по себе довольно странно. synchronized нужно использовать тогда, когда у потока должен быть эксклюзивный доступ.
0
0 / 0 / 0
Регистрация: 02.12.2015
Сообщений: 16
01.02.2017, 20:09  [ТС] 8
Цитата Сообщение от KuKu Посмотреть сообщение
Объяснять ненужность само по себе довольно странно.
Ненужность в данном случае подразумевается то что с использование synchronized или без него, результата нет! Хорошо, спасибо буду дальше копать...
0
345 / 141 / 51
Регистрация: 02.12.2015
Сообщений: 333
01.02.2017, 20:17 9
Цитата Сообщение от VirtusF12 Посмотреть сообщение
И как же поражденные потоки могут не увидеть, когда поток останавливается?
На многоядерных процессорах у каждого ядра свой кэш. И если потоки выполняются на разных ядрах у каждого потока будет своя копия данных. А синхронизируются данные в памяти если есть volatile или synchronized.
0
01.02.2017, 20:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.02.2017, 20:17
Помогаю со студенческими работами здесь

Передвижение спрайтов с разной скоростью
Проблема в следующем, что имеем 2 многоугольника, у одного скорость 0.5, у второго 1. На деле имеем...

Выдача udp с разной скоростью
Всем добра. Пытаюсь выдавать данные размером по 1000 байт с разной скоростью сетевуха 1Гбит/c. У...

Движение шариков по окружности с разной скоростью
Здравствуйте. Дана квадратная область с координатами от 1 до 100, внутри которой размещаются...

Движение pictureBox с разной скоростью по эллиптической траектории
Как сделать движение нескольких pictureBox с разной скоростью по эллипсу private void...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru