История изменений
Исправление iZEN, (текущая версия) :
package izenfire.produceconsume;
/**
* Объект-Значение
*/
class DataObject {
private volatile int value;
private boolean ready;
public DataObject() {
}
public synchronized void put(int newvalue) {
try {
Thread.sleep(1000);//Имитация временных затрат на модификацию Значения
} catch (InterruptedException iex) {
}
value = newvalue;
ready = true;
this.notifyAll();//сигнал всем заблокированным
}
public synchronized int take() throws InterruptedException {
while (!ready) {//ожидание модификации, снимающей блокировку
wait();
System.out.printf(" готово=%b ", ready);
}
ready = false;//значение прочтено
try {
Thread.sleep(2500);//Имитация временных затрат на чтение Значения
} catch (InterruptedException iex) {
}
return value;
}
}
/**
* Модификатор
*/
class Modifier extends Thread {
public boolean done;
private final int ID;
private final DataObject modifiable;
public Modifier(int ID, DataObject modifiable) {
this.ID = ID;
this.modifiable = modifiable;
}
@Override
public void run() {
int nv = 0;
while (!done) {
nv++;
modifiable.put(nv); //модифицировать Значение
System.out.printf("Modifier%d присвоил значение=%d; ", ID, nv);
}
}
}
/**
* Наблюдатель
*/
class Observer extends Thread {
public boolean done;
private final int ID;
private final DataObject observable;
public Observer(int ID, DataObject observable) {
this.ID = ID;
this.observable = observable;
}
@Override
public void run() {
int value = 0;
while (!done) {
try {
value = observable.take(); //получить модифицированное Значение
} catch (InterruptedException ex) {
}
System.out.printf("Observer%d увидел значение=%d.\n", ID, value);
}
}
}
public class ModifyObserveMain {
public static void main(String[] args) throws InterruptedException {
System.out.println("Старт симуляции.");
DataObject value = new DataObject();
Modifier modifier1 = new Modifier(1, value);
//Modifier modifier2 = new Modifier(2, value);
modifier1.start();
//modifier2.start();
Observer observer1 = new Observer(1, value);
//Observer observer2 = new Observer(2, value);
observer1.start();
//observer2.start();
//Система работает 30 секунд
Thread.sleep(30000);
modifier1.done = true;
//modifier2.done = true;
observer1.done = true;
//observer2.done = true;
synchronized (value) {
value.notifyAll(); //Будим всех заблокированных
}
System.out.println("Стоп симуляции.");
}
}
При этом объект класса DataObject имеет атомарную/квантовую/ природу своего содержимого: в нём можно хранить значение (в данном случае value типа int) до «взятия» значения кем-то.
Исправление iZEN, :
package izenfire.produceconsume;
/**
* Объект-Значение
*/
class DataObject {
private volatile int value;
private boolean ready;
public DataObject() {
}
public synchronized void put(int newvalue) {
try {
Thread.sleep(1000);//Имитация временных затрат на модификацию Значения
} catch (InterruptedException iex) {
}
value = newvalue;
ready = true;
this.notifyAll();//сигнал всем заблокированным
}
public synchronized int take() throws InterruptedException {
while (!ready) {//ожидание модификации, снимающей блокировку
wait();
System.out.printf(" готово=%b ", ready);
}
ready = false;//значение прочтено
try {
Thread.sleep(2500);//Имитация временных затрат на чтение Значения
} catch (InterruptedException iex) {
}
return value;
}
}
/**
* Модификатор
*/
class Modifier extends Thread {
public boolean done;
private final int ID;
private final DataObject modifiable;
public Modifier(int ID, DataObject modifiable) {
this.ID = ID;
this.modifiable = modifiable;
}
@Override
public void run() {
int nv = 0;
while (!done) {
nv++;
modifiable.put(nv); //модифицировать Значение
System.out.printf("Modifier%d присвоил значение=%d; ", ID, nv);
}
}
}
/**
* Наблюдатель
*/
class Observer extends Thread {
public boolean done;
private final int ID;
private final DataObject observable;
public Observer(int ID,
DataObject observable
) {
this.ID = ID;
this.observable = observable;
}
@Override
public void run() {
int value = 0;
while (!done) {
try {
value = observable.take(); //получить модифицированное Значение
} catch (InterruptedException ex) {
}
System.out.printf("Observer%d увидел значение=%d.\n", ID, value);
}
}
}
public class ModifyObserveMain {
public static void main(String[] args) throws InterruptedException {
System.out.println("Старт симуляции.");
DataObject value = new DataObject();
Modifier modifier1 = new Modifier(1, value);
//Modifier modifier2 = new Modifier(2, value);
modifier1.start();
//modifier2.start();
Observer observer1 = new Observer(1, value);
//Observer observer2 = new Observer(2, value);
observer1.start();
//observer2.start();
//Система работает 30 секунд
Thread.sleep(30000);
modifier1.done = true;
//modifier2.done = true;
observer1.done = true;
//observer2.done = true;
synchronized (value) {
value.notifyAll(); //Будим всех заблокированных
}
System.out.println("Стоп симуляции.");
}
}
При этом объект класса DataObject имеет атомарную/квантовую/ природу своего содержимого: в нём можно хранить значение (в данном случае value типа int) до «взятия» значения кем-то.
Исходная версия iZEN, :
Вот что накропал совместно с авторами JLS
package izenfire.produceconsume;
/**
* Объект-Значение
*/
class DataObject {
private volatile int value;
private boolean ready;
public DataObject() {
}
public synchronized void put(int newvalue) {
try {
Thread.sleep(1000);//Имитация временных затрат на модификацию Значения
} catch (InterruptedException iex) {
}
value = newvalue;
ready = true;
this.notifyAll();//сигнал всем заблокированным
}
public synchronized int take() throws InterruptedException {
while (!ready) {//ожидание модификации, снимающей блокировку
wait();
System.out.printf(" готово=%b ", ready);
}
ready = false;//значение прочтено
try {
Thread.sleep(2500);//Имитация временных затрат
} catch (InterruptedException iex) {
}
return value;
}
}
/**
* Модификатор
*/
class Modifier extends Thread {
public boolean done;
private final int ID;
private final DataObject modifiable;
public Modifier(int ID, DataObject modifiable) {
this.ID = ID;
this.modifiable = modifiable;
}
@Override
public void run() {
int nv = 0;
while (!done) {
nv++;
modifiable.put(nv); //модифицировать Значение
System.out.printf("Modifier%d присвоил значение=%d; ", ID, nv);
}
}
}
/**
* Наблюдатель
*/
class Observer extends Thread {
public boolean done;
private final int ID;
private final DataObject observable;
public Observer(int ID,
DataObject observable
) {
this.ID = ID;
this.observable = observable;
}
@Override
public void run() {
int value = 0;
while (!done) {
try {
value = observable.take(); //получить модифицированное Значение
} catch (InterruptedException ex) {
}
System.out.printf("Observer%d увидел значение=%d.\n", ID, value);
}
}
}
public class ModifyObserveMain {
public static void main(String[] args) throws InterruptedException {
System.out.println("Старт симуляции.");
DataObject value = new DataObject();
Modifier modifier1 = new Modifier(1, value);
//Modifier modifier2 = new Modifier(2, value);
modifier1.start();
//modifier2.start();
Observer observer1 = new Observer(1, value);
//Observer observer2 = new Observer(2, value);
observer1.start();
//observer2.start();
//Система работает 30 секунд
Thread.sleep(30000);
modifier1.done = true;
//modifier2.done = true;
observer1.done = true;
//observer2.done = true;
synchronized (value) {
value.notifyAll(); //Будим всех заблокированных
}
System.out.println("Стоп симуляции.");
}
}
При этом объект класса DataObject имеет атомарную/квантовую/ природу своего содержимого: в нём можно хранить значение (в данном случае value типа int) до «взятия» значения кем-то.