×
Traktatov.net » Философия Java » Читать онлайн
Страница 383 из 395 Настройки

//: concurrency/ExchangerDemo.java import java.util.concurrent.*; import java.util.*; i mport net.mi ndvi ew.uti1.*:

class ExchangerProducer implements Runnable { private Generator generator; private Exchanger> exchanger; private List holder; ExchangerProducer(Exchanger

  • > exchg, Generator gen, List holder) { exchanger = exchg; generator = gen; this.holder = holder;

    }

    public void run() { try {

    while(IThread.interruptedO) {

    for(int i =0; i < ExchangerDemo size; i++)

    hoi der.add(generator. nextO); // Заполненный контейнер заменяется пустым: holder = exchanger exchange(holder);

    }

    } catchdnterruptedException e) {

    // Приемлемый способ завершения.

    }

    class ExchangerConsumer implements Runnable { private Exchanger> exchanger; private List holder; private volatile T value;

    ExchangerConsumer(Exchanger> ex, List holder){ exchanger = ex; this.holder = holder;

    }

    public void runO {

    } catch(InterruptedException e) {

    // Приемлемый способ завершения

    }

    System out.printlnC'HToroBoe значение- " + value).

    }

    }

    public class ExchangerDemo { static int size = 10; static int delay = 5; // Секунды

    public static void main(String[] args) throws Exception { if(args.length > 0)

    size = new lnteger(args[0]), if(args.length > 1)

    delay = new Integer(args[l]); ExecutorService exec = Executors.newCachedThreadPoolО. Exchanger> xc = new Exchanger

    producerList = new CopyOnWriteArrayList(). consumerList = new CopyOnWriteArrayList(); exec.execute(new ExchangerProducer(xc.

    BasicGenerator.create(Fat.class). producerList)); exec.execute(

    new ExchangerConsumer(xc.consumerLi st)); TimeUni t.SECONDS.sieep(delay); exec shutdownNowO;

    }

    } /* Output:

    Итоговое значение: Fat id: 29999 *///.-

    В методе main() для обеих задач создается один объект Exchanger, а для перестановки создаются два контейнера CopyOnWriteArrayList. Эта разновидность List нормально переносит вызов метода remove() при перемещении по списку, не выдавая исключения ConcurrentModificationException. ExchangerProducer заполняет список, а затем меняет местами заполненный список с пустым, передаваемым от ExchangerConsumer. Благодаря Exchanger заполнение списка происходит одновременно с использованием уже заполненного списка.

    Моделирование

    Одна из самых интересных областей применения параллельных вычислений — всевозможные имитации и моделирование. Каждый компонент модели оформляется в виде отдельной задачи, что значительно упрощает его программирование.

    whi 1е(!Thread interruptedO) {

    holder = exchanger.exchange(holder), for(T x . holder) {

    value = x; // Выборка значения holder remove(x); // Нормально для

    CopyOnWri teArrayLi st

    Примеры HorseRace.java и GreenhouseScheduler.java, приведенные ранее, тоже можно считать своего рода имитаторами.

    Модель кассира

    В этой классической модели объекты появляются случайным образом и обслуживаются за случайное время ограниченным количеством серверов. Моделирование позволяет определить идеальное количество серверов. Продолжительность обслуживания в следующей модели зависит от клиента и определяется случайным образом. Вдобавок мы не знаем, сколько новых клиентов будет прибывать за каждый период времени, поэтому эта величина тоже определяется случайным образом.