Skip to content

Instantly share code, notes, and snippets.

@Shtaba09
Created November 26, 2018 20:48
Show Gist options
  • Save Shtaba09/f3aa4af07fc7605e5c1fc937cef1c17e to your computer and use it in GitHub Desktop.
Save Shtaba09/f3aa4af07fc7605e5c1fc937cef1c17e to your computer and use it in GitHub Desktop.
Механизм wait\notifyi в примере
package com.javarush.task.task27.task2709;
public class ConsumerTask implements Runnable {
private TransferObject transferObject;
protected volatile boolean stopped;
public ConsumerTask(TransferObject transferObject) {
this.transferObject = transferObject;
new Thread(this, "ConsumerTask").start();
}
public void run() {
while (!stopped){
synchronized (transferObject){
transferObject.get();}
}
}
public void stop() {
stopped = true;
}
}
package com.javarush.task.task27.task2709;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
public class ProducerTask implements Runnable {
private TransferObject transferObject;
protected volatile boolean stopped;
static volatile AtomicInteger i = new AtomicInteger(0);
public ProducerTask(TransferObject transferObject) {
this.transferObject = transferObject;
new Thread(this, "ProducerTask").start();
}
public void run() {
while (!stopped) {
synchronized (transferObject){
transferObject.put(i.incrementAndGet());
}}
}
public void stop() {
stopped = true;
}
}
package com.javarush.task.task27.task2709;
/*
Producer–consumer
*/
public class Solution {
public static void main(String args[]) throws InterruptedException {
TransferObject transferObject = new TransferObject();
ProducerTask producerTask = new ProducerTask(transferObject);
ConsumerTask consumerTask = new ConsumerTask(transferObject);
Thread.sleep(50);
producerTask.stop();
consumerTask.stop();
}
}
package com.javarush.task.task27.task2709;
public class TransferObject {
private int value;
protected volatile boolean isValuePresent = false; //use this variable
public synchronized int get() {
while (!isValuePresent){
try {
this.wait();
} catch (InterruptedException e) {
}
}
System.out.println("Got: " + value);
isValuePresent=false;
this.notify();
return value;
}
public synchronized void put(int value) {
while (isValuePresent){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.value = value;
System.out.println("Put: " + value);
isValuePresent=true;
this.notify();
}
}
taskKey="com.javarush.task.task27.task2709"
Producer–consumer
В классе TransferObject расставь вызовы методов wait/notify/notifyAll,
чтобы обеспечить последовательное создание и получение объекта.
В методах run классов ConsumerTask и ProducerTask создай необходимые synchronized блоки.
Ожидаемый вывод:
...
Put: M
Got: M
Put: N
Got: N
Put: K
Got: K
...
где M, N, K - числа
Метод main не участвует в тестировании
P.S. Всегда старайся использовать concurrent коллекции вместо ручной реализации wait/notify/notifyAll.
Задачи подобные этой позволяют лучше понять основы работы многопоточных приложений.
Требования:
1. В методе run класса ConsumerTask должен содержаться synchronized блок, монитор - transferObject.
2. В методе run класса ProducerTask должен содержаться synchronized блок, монитор - transferObject.
3. Метод get класса TransferObject должен ждать появления value, и возвращать его после того, как оно появится.
4. Метод put класса TransferObject должен ждать пока value заберут и обновлять его значение после того, как оно пропадет.
5. Метод get класса TransferObject должен устанавливать флаг isValuePresent в false и уведомлять другие нити ожидающие освобождения монитора перед возвратом значение поля value.
6. Метод put класса TransferObject должен устанавливать флаг isValuePresent в true и уведомлять другие нити ожидающие освобождения монитора после обновления значение поля value.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment