Программирование на языке Java


Легковесные процессы и синхронизация - часть 7


• wait — приводит к тому, что текущий подпроцесс отдает управление и переходит в режим ожидания — до тех пор пока другой под-процесс не вызовет метод notify с тем же объектом.

• notify — выводит из состояния ожидания первый из подпроцессов, вызвавших wait с данным объектом.

• notifyAll — выводит из состояния ожидания все подпроцессы, вызвавшие wait с данным объектом.

Ниже приведен пример программы с наивной реализацией проблемы поставщик-потребитель. Эта программа состоит из четырех простых классов: класса Q, представляющего собой нашу реализацию очереди, доступ к которой мы пытаемся синхронизовать; поставщика (класс Producer), выполняющегося в отдельном подпроцессе и помещающего данные в очередь; потребителя (класс Consumer), тоже представляющего собой подпроцесс и извлекающего данные из очереди; и, наконец, крохотного класса PC, который создает по одному объекту каждого из перечисленных классов.

class Q {

int n;

synchronized int get() {

System.out.println("Got: " + n);

return n;

}

synchronized void put(int n) {

this.n = n;

System.out. println("Put: " + n);

} }

class Producer implements Runnable {

Q q;

Producer(Q q) {

this.q = q;

new Thread(this, "Producer").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, "Consumer").start();

}

public void run() {

while (true) {

q.get();

}

} }

class PC {

public static void main(String args[]) {

Q q = new Q();

new Producer(q);

new Consumer(q);

} }

Хотя методы put и get класса Q синхронизованы, в нашем примере нет ничего, что бы могло помешать поставщику переписывать данные по того, как их получит потребитель, и наоборот, потребителю ничего не мешает многократно считывать одни и те же данные. Так что вывод программы содержит вовсе не ту последовательность сообщений, которую нам бы хотелось иметь:

С:\> java PC

Put: 1

Got: 1

Got: 1

Got: 1




- Начало -  - Назад -  - Вперед -