Page 71 - 4657
P. 71
споживачу нічого не заважає багаторазово зчитувати ті самі
дані. Так що висновок програми містить зовсім не ту
послідовність повідомлень, що нам би хотілося мати:
С:\> java PC
Put: 1
Got: 1
Got: 1
Got: 1
Got: 1
Got: 1
Put: 2
Put: 3
Put: 4
Put: 5
Put: 6
Put: 7
Got: 7
Як бачите, після того, як постачальник поміщає в перемінну
n значення 1, споживач починає працювати і витягає це
значення 5 разів підряд. Положення можна виправити, якщо
постачальник буде при занесенні нового значення
встановлювати прапор, наприклад, заносити в логічну перемінну
значення true, після чого буде в циклі перевіряти її значення
доти поки постачальник не обробить дані і не скине прапор у
false.
Правильним шляхом для одержання того ж результату в
Java є використання викликів wait і notify для передачі сигналів
в обох напрямках. Усередині методу get ми чекаємо (виклик
wait), поки Producer не сповістить нас (notify), що для нас готова
чергова порція даних. Після того, як ми обробимо ці дані в
методі get, ми сповіщаємо об'єкт класу Producer (знову виклик
notify) про те, що він може передавати наступну порцію даних.
Відповідно, усередині методу put, ми чекаємо (wait), поки
Consumer не обробить дані, потім ми передаємо нові дані і
сповіщаємо (notify) про це об'єкт-споживач. Нижче приведений
переписаний зазначеним образом клас Q.
69