void setObject data throws Interrupted Exception lock try
ПРОИЗВОДИТЕЛЬ • Решение с помощью событий void set(Object data) throws Interrupted. Exception { lock(); try { while (data != null) not. Full. await(); this. data = data; not. Empty. signal(); } finally { lock. unlock(); } } Java Advanced / java. util. concurrent
BOUNDED BUFFER class Bounded. Buffer { final Lock lock = new Reentrant. Lock(); final Condition not. Full = lock. new. Condition(); final Condition not. Empty = lock. new. Condition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws Interrupted. Exception { … } public Object take() throws Interrupted. Exception { … } } Java Advanced / java. util. concurrent
BOUNDED BUFFER public void put(Object x) throws Interrupted. Exception { lock(); try { while (count == items. length) not. Full. await(); items[putptr] = x; if (++putptr == items. length) putptr = 0; ++count; not. Empty. signal(); } finally { lock. unlock(); } } Java Advanced / java. util. concurrent
BOUNDED BUFFER public Object take() throws Interrupted. Exception { lock(); try { while (count == 0) not. Empty. await(); Object x = items[takeptr]; if (++takeptr == items. length) takeptr = 0; --count; not. Full. signal(); return x; } finally { lock. unlock(); } } Java Advanced / java. util. concurrent
УПРАВЛЕНИЕ ЗАДАНИЯМИ ЧАСТЬ 2 Java Advanced / java. util. concurrent
ИСПОЛНИТЕЛИ-2 • Интерфейс Executor. Service • • submit(Runnable) – выполнить задание Future<V> submit(Callable<V>) – выполнить функцию List<Future> invoke. All(List<Callable>) – выполнить все функции Future invoke. Any(List<Callable>) – успешно выполнить функцию Java Advanced / java. util. concurrent
ПРИМЕР class Task implements Runnable { private int counter; public Task(int num) { this. counter = num; } public void run() { while (counter-- > 0) { System. out. println(Thread. current. Thread() + ": " + counter); Thread. yield(); } } } public class Main { public static void main(String[] args) { Random rand = new Random(); Executor. Service exec = Executors. new. Fixed. Thread. Pool(2); for (int i = 0; i < 5; i++) { execute(new Task(Math. abs(rand. next. Int())%10)); } exec. shutdown(); } } Java Advanced / java. util. concurrent
ПРИМЕР-2 class Callable. Task implements Callable<Integer> { private int counter; private final int number; public Callable. Task(int num) { this. counter = num; this. number = num; } public Integer call() { while (counter-- > 0) { System. out. println(Thread. current. Thread() + ": " + counter); Thread. yield(); } return number; } } Java Advanced / java. util. concurrent
ПРИМЕР-2 public class Main. Callable { public static void main(String[] args) { Array. List<Future<Integer>> results = new Array. List<>(); Executor. Service exec = Executors. new. Cached. Thread. Pool(); for (int i = 0; i < 5; i++) { results. add(exec. submit(new Callable. Task(i))); } exec. shutdown(); for (Future<Integer> fi : results) { try { System. out. println(fi. get()); } catch (Interrupted. Exception | Execution. Exception e) { e. print. Stack. Trace(); } try { System. out. println(fi. get(5, Time. Unit. SECONDS)); } catch (Interrupted. Exception | Execution. Exception e | Timeout. Exception e) { e. print. Stack. Trace(); } } Java Advanced / java. util. concurrent
ПРИМЕР class Daemon. Thread. Factory implements Thread. Factory { public Thread new. Thread(Runnable r) { Thread t = new Thread(r); t. set. Daemon(true); return t; } } public class Main. Thread. Factory { public static void main(String[] args) { Array. List<Future<Integer>> results = new Array. List<Future<Integer>>(); Executor. Service exec = Executors. new. Cached. Thread. Pool(new Daemon. Thread. Factory()); for (int i = 0; i < 5; i++) { results. add(exec. submit(new Callable. Task(i*100))); } exec. shutdown(); for (Future<Integer> fi : results) { try { System. out. println(fi. get()); } catch (Interrupted. Exception | Execution. Exception e) { e. print. Stack. Trace(); } } Java Advanced / java. util. concurrent
ОТЛОЖЕННОЕ ИСПОЛНЕНИЕ • Интерфейс Scheduled. Executor. Service • schedule(callable, timeout) – исполнить через timeout • schedule(runnable, timeout? ) – исполнить через timeout • shedule. At. Fixed. Rate(runnable, initial. Delay, period) – периодическое исполнение • schedule. With. Fixed. Delay(runnable, initial. Delay, delay) – исполнение с равными интервалами • Все методы возвращают Scheduled. Future Java Advanced / java. util. concurrent
РЕАЛИЗАЦИЯ ОТЛОЖЕННОГО ИСПОЛНЕНИЯ • Класс Scheduled. Thread. Pool. Executor Java Advanced / java. util. concurrent
ПРИМИТИВЫ СИНХРОНИЗАЦИИ ЧАСТЬ 3 Java Advanced / java. util. concurrent
ПРИМЕР. СКАЧКИ class Horse implements Runnable { private int strides = 0; private static Random rand = new Random(47); private static Cyclic. Barrier barrier; public Horse(Cyclic. Barrier b) { barrier = b; } public void run() { try { while(!Thread. interrupted()) { synchronized(this) { strides += rand. next. Int(3); // Produces 0, 1 or 2 } barrier. await(); } } catch(Interrupted. Exception e) {// Приемлемый вариант выхода } catch(Broken. Barrier. Exception e) {throw new Runtime. Exception(e); } } … } Java Advanced / java. util. concurrent
ПРИМЕР. СКАЧКИ public class Horse. Race { private List<Horse> horses = new Array. List<Horse>(); private Executor. Service exec = Executors. new. Cached. Thread. Pool(); private Cyclic. Barrier barrier; public Horse. Race(int n. Horses) { barrier = new Cyclic. Barrier(n. Horses, new Runnable() { public void run() { for(Horse horse : horses) System. out. println(horse. tracks()); for(Horse horse : horses) if(horse. get. Strides() >= FINISH_LINE) { System. out. println(horse + "won!"); exec. shutdown. Now(); return; } } }); for(int i = 0; i < n. Horses; i++) { Horse horse = new Horse(barrier); horses. add(horse); execute(horse); } } Java Advanced / java. util. concurrent
ПРИМЕР // Часть основной задачи: // Ожидание по объекту Count. Down. Latch: class Task. Portion implements Runnable { … private final Count. Down. Latch latch; Task. Portion(Count. Down. Latch latch) { this. latch = latch; } public void run() { try { do. Work(); latch. count. Down(); } catch(Interrupted. Exception ex) { // Приемлемый вариант выхода } } } class Waiting. Task implements Runnable { … private final Count. Down. Latch latch; Waiting. Task(Count. Down. Latch latch) { this. latch = latch; } public void run() { try { latch. await(); do. Wrk(); System. out. println("barrier passed"); } catch(Interrupted. Exception ex) { System. out. println(this + " interrupted"); } } } Java Advanced / java. util. concurrent
ПРИМЕР class Exchanger. Producer<T> implements Runnable { private Generator<T> generator; private Exchanger<List<T>> exchanger; private List<T> holder; Exchanger. Producer(Exchanger<List<T>> exchg, Generator<T> gen, List<T> holder) { exchanger = exchg; generator = gen; this. holder = holder; } public void run() { try { while(!Thread. interrupted()) { for(int i = 0; i < Exchanger. Demo. size; i++) holder. add(generator. next()); holder = exchanger. exchange(holder); } } catch(Interrupted. Exception e) {} } } Java Advanced / java. util. concurrent
ПРИМЕР class Exchanger. Consumer<T> implements Runnable { private Exchanger<List<T>> exchanger; private List<T> holder; private volatile T value; Exchanger. Consumer(Exchanger<List<T>> ex, List<T> holder){ exchanger = ex; this. holder = holder; } public void run() { try { while(!Thread. interrupted()) { holder = exchanger. exchange(holder); for(T x : holder) { value = x; // Выборка значения holder. remove(x); } } } catch(Interrupted. Exception e) {} System. out. println("Final value: " + value); } } Java Advanced / java. util. concurrent
ПРИМЕР public class Exchanger. Demo { static int size = 10; static int delay = 5; // Секунды public static void main(String[] args) throws Exception { Executor. Service exec = Executors. new. Cached. Thread. Pool(); Exchanger<List<Fat>> xc = new Exchanger<List<Fat>>(); List<Fat> producer. List = new Copy. On. Write. Array. List<Fat>(), consumer. List = new Copy. On. Write. Array. List<Fat>(); execute(new Exchanger. Producer<Fat>(xc, Basic. Generator. create(Fat. class), producer. List)); execute( new Exchanger. Consumer<Fat>(xc, consumer. List)); Time. Unit. SECONDS. sleep(delay); exec. shutdown. Now(); } } Java Advanced / java. util. concurrent
АТОМАРНЫЕ ОПЕРАЦИИ ЧАСТЬ 4 Java Advanced / java. util. concurrent
УСЛОВНАЯ ЗАПИСЬ • compare. And. Set(old, new) • Если текущее значение равно old • Установить значение в new • Идиома do { old = v. get(); new = process(old); } while (v. compare. And. Set(old, new)); Java Advanced / java. util. concurrent
НЕБЛОКИРУЮЩИЙ СЧЕТЧИК public final class Counter { private long value = 0; private Atomic. Integer value; public synchronized long get. Value() { return value; } public int get. Value() { return value. get(); } public int increment() { int v; public synchronized long increment() { do { return ++value; v = value. get(); } while (!value. compare. And. Set(v, v + } 1)); return v + 1; } } public class Nonblocking. Counter { Java Advanced / java. util. concurrent
АТОМАРНЫЕ ПЕРЕМЕННЫЕ • Типы • • Atomic. Boolean Atomic. Integer Atomic. Long Atomic. Reference • Операции • Обычные Java Advanced / java. util. concurrent
- Slides: 54