LINUX.ORG.RU

История изменений

Исправление 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) до «взятия» значения кем-то.