Форум программистов, компьютерный форум, киберфорум
Наши страницы
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
sfisher
0 / 0 / 0
Регистрация: 17.01.2015
Сообщений: 20
#1

Межпотоковые коммуникации

04.02.2015, 14:56. Просмотров 610. Ответов 7
Метки нет (Все метки)

В учебнике Шилдта встретил программу по теме Межпотоковые коммуникации, не могу понять как здесь работает boolean valueSet? Что за чем выполняется, кто может объясните пожалуйста.

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
55
56
57
58
59
60
61
62
63
// Правильная реализация поставщика и потребителя.
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
while(!valueSet) try {
wait () ;
}
catch(InterruptedException e) {
System.out.println("InterruptedException перехвачено");
}
System.out.println("Получено: " + n) ;
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while(valueSet) try {
wait () ;
} catch(InterruptedException e) {
System.out.println("InterruptedException перехвачено");
}
this.n = n;
valueSet = true;
System.out.println("Отправлено: " + n) ;
notify();v }
}
 
class Producer implements Runnable {
Q q;
Producer(Q q) {
this. q = q;
new Thread(this,"Поставщик").start ();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}
 
class Consumer implements Runnable {
Q q; 
Consumer(Q q) {
this.q = q;
new Thread(this, "Потребитель").start ();
}
public void run() {
while(true) {
q.get () ;
}
}
}
 
class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer (q) ;
new Consumer (q) ;
System.out.println("Для останова нажмите Control-C.");
}
}
Добавлено через 36 минут
Программа выводит:

Отправлено: 1
Получено: 1
Отправлено: 2
Получено: 2
Отправлено: 3
Получено: 3
Отправлено: 4
Получено: 4
Отправлено: 5
Получено: 5

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.02.2015, 14:56
Ответы с готовыми решениями:

Интерфейс и лаги в коммуникации
Есть у нас претендующая на реалтайм программа, использующая интерфейс,...

Механизм коммуникации: Call Center
Мне предстоит разрабатывать что-то вроде call center с автоматической...

3 пути коммуникации в модели TCP/IP
Здравствуйте, уважаемые! Согласно описанию модели TCP IP, возможны следующие...

Архитектура для коммуникации объектов
Здравствуйте! Есть базовый объект, который является контейнером и хранит в...

Протокол для надёжной коммуникации по RS485.
Здравствуйте, друзья :) ! На очередной итерации моего Мармезонского балета...


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

Или воспользуйтесь поиском по форуму:
7
AMufu
16 / 16 / 6
Регистрация: 05.09.2012
Сообщений: 223
04.02.2015, 20:34 #2
Лучший ответ Сообщение было отмечено sfisher как решение

Решение

valueSet это флажок, который запускает методы put() и get(). Классы Consumer и Producer пробуют выполнить их постоянно, но сами методы исполняют действие только когда valueSet пребывает в определенном состоянии (в случае с put() метод исполняет полезную работу по изменению n только когда valueSet false.). Выполнив работу метод изменяет состояние флажка valueSet и оповещает другие методы.
1
sfisher
0 / 0 / 0
Регистрация: 17.01.2015
Сообщений: 20
04.02.2015, 22:51  [ТС] #3
AMufu не могли бы вы подробнее описать какой valueSet здесь за что отвечает в методах get и put, почему в get стоит везде false а в put стоит true? Буду очень благодарен. Спасибо.
0
AMufu
16 / 16 / 6
Регистрация: 05.09.2012
Сообщений: 223
05.02.2015, 03:29 #4
Лучший ответ Сообщение было отмечено sfisher как решение

Решение

Цитата Сообщение от sfisher Посмотреть сообщение
AMufu не могли бы вы подробнее описать какой valueSet здесь за что отвечает в методах get и put, почему в get стоит везде false а в put стоит true? Буду очень благодарен. Спасибо.
Что имеется ввиду под "какой valueSet здесь за что отвечает ". valueSet только один и каждый метод ему присваивает значения поочередно - put изменяет n только тогда, когда valueSet false, а изменив n устанавливает valueSet true. Метод set считывает n только тогда, когда valueSet true , а изменив n устанавливает valueSet false. Так они поочередно делают работу, изменяют valueSet и оповещают друг друга через notify.
1
OneWayTicket
0 / 0 / 0
Регистрация: 25.08.2015
Сообщений: 1
25.08.2015, 20:37 #5
Хочу присоединиться к интересу sfisher разобраться в данном примере. Сам дошел в Шилдте до этого примера и подвис немного. Я понял, что valueSet здесь отвечает за переключение между методами "Set" и "Put", но вывод этой программы не совпадает с тем алгоритмом выполнения программы, который вижу я.
Я опишу порядок выполнения в том виде в котором я его вижу. Ткните пожалуйста носом где я не прав.
начну с строчки 59: new Producer (q) ;
После компиляции этой строки мы попадаем в конструктор "Producer (Q q)" класса "Producer";
В нем запускаем первый поток, после чего выполнение переходит в метод "put()".
В данный момент времени как я понимаю значение valueSet установленное по умолчанию равно false. ТОЕСТЬ
условие "while(valueSet) " ВЫПОЛНЯЕТСЯ и работа нашего потока приостанавливается до момента, пока в методе "get()" не будет вызван метод "notify()".
После того как был запущен первый поток со строки "33: new Thread(this,"Поставщик").start ();" - управление передается методу "main" в строку "60: new Consumer (q) ;" . Пройдя череду аналогичных событий запускается второй поток и мы оказываемся в методе "get()". Здесь условие "while(!valueSet)" НЕ ВЫПОЛНЯЕТСЯ (значение valueSet все еще равно false), и условие тела этого цикла("wait()") также не выполниться. ТОЕСТЬ продолжается выполнение метода "get()" со строки 12: System.out.println("Получено: " + n) ;. Здесь у меня начинается коллапс))) Раз метод "put()" еще спит и поле "int n;" в классе Q еще неинициализировано значит в консоль должно вывести вначале "Получено: null".
затем стока "14: notify();" - пробудит первый поток, в котором переменная "int n" проинициализируется значением "0", после чего логика выполнения мне ясна.

Тоесть вывод этой программы я выжу как:
Получено: null
Отправлено: 0
Получено: 0
Отправлено: 1
Получено: 1
......
......

очень нуждаюсь хоть в каком-то совете)) Спасибо
0
aleksandy
629 / 521 / 165
Регистрация: 01.04.2010
Сообщений: 1,843
26.08.2015, 01:32 #6
Цитата Сообщение от OneWayTicket Посмотреть сообщение
поле "int n;" в классе Q еще неинициализировано
Поля классов всегда инициализируются значениями по умолчанию, если не указано иное. Для примитивных типов, это 0 для чисел и false для boolean. Все ссылки инициализируются null-ом.
0
osrcproject
3 / 3 / 0
Регистрация: 01.05.2012
Сообщений: 16
26.01.2017, 18:30 #7
Цитата Сообщение от OneWayTicket Посмотреть сообщение
В данный момент времени как я понимаю значение valueSet установленное по умолчанию равно false. ТОЕСТЬ
условие "while(valueSet) " ВЫПОЛНЯЕТСЯ и работа нашего потока приостанавливается до момента, пока в методе "get()" не будет вызван метод "notify()".
Условие наоборот не выполняется и в таком случае оператор try опускается, счётчик увеличивается, а вот valueSet становится true, при этом потоку запущенному параллельно разрешается исполнение notify(), так как возможно он уже перешёл в режим wait()
Сам дочитал только до этого момента, но сразу не понял как именно происходит приостановка и возобновление потока. Получается это только для экономии процессорного времени? Иначе тоже самое можно было выставить в условии цикла. Вот сейчас пролистал пару страниц назад и ещё раз прочёл, автор так и указал, что это всё можно реализовать на циклах, но для экономии ЦП существуют методы )))))
0
osrcproject
3 / 3 / 0
Регистрация: 01.05.2012
Сообщений: 16
28.01.2017, 12:18 #8
да уж снова мимо
0
28.01.2017, 12:18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru