
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent Синхронизаторы.
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent Синхронизаторы.
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent Синхронизаторы.
- •java.util.concurrent Синхронизаторы.
- •java.util.concurrent Синхронизаторы.
- •java.util.concurrent.atomic Классы с атомарными
- •java.util.concurrent.atomic Основные методы атомарных классов (1)
- •java.util.concurrent.atomic Основные методы
- •java.util.concurrent.atomic Классы с атомарными операциями. Пример.
- •Коллекции Java
- •Пакет java.util. Коллекции
- •Пакет java.util. Коллекции
- •Пакет java.util. Коллекции Интерфейсы
- •Пакет java.util. Коллекции Методы интерфейса Collection (1)
- •Пакет java.util. Коллекции Методы интерфейса Collection (2)
- •Пакет java.util. Коллекции Интерфейсы *Set
- •Пакет java.util. Коллекции Интерфейсы List и ListIterator
- •Пакет java.util. Коллекции Методы интерфейса List (1)
- •Пакет java.util. Коллекции Методы интерфейса List (2)
- •Пакет java.util. Коллекции Интерфейс Iterator
- •Пакет java.util. Коллекции Интерфейс ListIterator
- •Пакет java.util. Коллекции Интерфейс Queue
- •Пакет java.util. Коллекции Интерфейс Deque (1)
- •Пакет java.util. Коллекции Интерфейсы *Map
- •Пакет java.util. Коллекции Методы интерфейса Map (1)
- •Пакет java.util. Коллекции Методы интерфейса Map (2)
- •Пакет java.util. Коллекции
- •Пакет java.util. Классы коллекций (1)
- •Пакет java.util. Классы коллекций (2)
- •Пакет java.util. Классы коллекций (3)
- •Пакет java.util.concurrent
- •Пакет java.util.concurrent Классы "параллельных"
- •Пакет java.util.concurrent Классы "параллельных"
- •Пакет java.util.concurrent Классы "параллельных"
- •Пакет java.util. Коллекции
- •Пакет java.util. Классы коллекций (4)
- •Пакет java.util. Классы коллекций (5)
- •Пакет java.util.concurrent Интерфейсы и классы
- •Пакет java.util. Коллекции Сравнение коллекций

java.util.concurrent
Синхронизаторы. Обменники (1)
Обменник – это параметризованный класс Exchanger пакета java.util.concurrent, с помощью которого можно осуществлять передачу данных
между потоками, не заботясь о синхронизации (она реализуется внутренними средствами класса).
В двух потоках, которым нужно обменяться данными, вызывается метод exchange() экземпляра класса Exchanger, доступного каждому из них. В
качестве аргумента метода указывается значение (его тип должен быть приводим к параметру используемого экземпляра обменника), которое должно быть отдано другому потоку:
V exchange( V sendingValue )
Поток, вызвавший этот метод, засыпает до тех пор, пока какой-либо другой поток не вызовет этот же метод этого же экземпляра обменника.
Существует возможность указать продолжительность тайм-аута ожидания,
после истечения которого проснувшийся поток получит для обработки исключение TimeoutException:
V exchange( V sendingValue, long timeout, TimeUnit tUnit )
Обменники можно использовать и как средство синхронизации. Часто это оказывается значительно более удобным, чем другие средства.
Вычислим параллельно суммы элементов строк матрицы с использованием обменников.

java.util.concurrent
Синхронизаторы. Барьеры и обменники (1)
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Exchanger; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Main { |
|
|
|
private static int matrix[ ][ ] = |
|
||
{ |
… |
}; |
// инициализация или чтение матрицы |
private static int results[ ]; static Boolean flag = false;
private static class Summator extends Thread {
int row; |
// индекс строки для экземпляра сумматора |
CyclicBarrier barrier; |
// барьерный синхронизатор |
Summator( CyclicBarrier barrier, int row ) { // конструктор сумматора this.barrier = barrier;
this.row = row;
}

java.util.concurrent
Синхронизаторы. Барьеры и обменники (2)
public void run( ) { |
// метод потока |
int columns = matrix[ row ].length; |
|
int sum = 0; |
|
for ( int i = 0; i < columns; i++ ) { |
// собственно суммирование |
sum += matrix[ row ][ i ]; |
|
}
results[ row ] = sum;
System.out.println( "Сумма элементов строки " + row + " равна: " + sum ); try { // ожидание остальных
barrier.await( );
}catch ( InterruptedException ex ) { ex.printStackTrace( );
}catch ( BrokenBarrierException ex ) { ex.printStackTrace( );
}
}
}

java.util.concurrent
Синхронизаторы. Барьеры и обменники (3)
public static void main( String args[ ] ) { // здесь объявления
final int rows = matrix.length; results = new int[ rows ];
final Exchanger<Integer> myExchanger = new Exchanger<Integer>( );
Runnable merger = new Runnable( ) { |
// внутренний класс |
|
public void run( ) { |
// сложение сумм по строкам |
|
int sum = 0; |
|
|
for ( int i = 0; i < rows; i++ ) |
|
|
sum += results[ i ]; |
|
|
try { |
// обмен данными и синхронизация с основным потоком |
myExchanger.exchange( Integer.valueOf( sum ) ); } catch( InterruptedException ex ) {
ex.printStackTrace( );
}
System.out.println( "Сумма элементов матрицы равна: " + sum );
}
};

java.util.concurrent
Синхронизаторы. Барьеры и обменники (4)
CyclicBarrier barrier = new CyclicBarrier( rows, merger );
for ( int i = 0; i < rows; i++ ) { // запуск всех сумматоров new Summator( barrier, i ).start( );
}
System.out.println( "Ожидание..." );
Integer result = myExchanger.exchange( 0 ); // получение результатов System.out.println( "Вычисления закончены. " + result );
}
}
Сумма элементов строки 0 равна: 15 (8) Сумма элементов строки 2 равна: 77 (10) Сумма элементов строки 4 равна: 100 (12) Ожидание... (1)
Сумма элементов строки 1 равна: 13 (9) Сумма элементов строки 3 равна: 48 (11) Сумма элементов строки 5 равна: 23 (13) Сумма элементов матрицы равна: 276 (13) Вычисления закончены.276 (1)

java.util.concurrent Синхронизаторы.
Защелка (1)
Защелка (или щеколда) – средство синхронизации, которое используется для того, чтобы один или несколько потоков могли дождаться выполнения заданного количества операций в других потоках.
Класс CountDownLatch пакета java.util.concurrent является соответствующим средством синхронизации. Он работает по принципу таймера, только отсчеты вырабатываются программно, а не кварцевым генератором.
При создании экземпляра класса его внутренний счетчик инициализируется
начальным значением, передаваемым конструктору. Значение счетчика может быть уменьшено на 1 путем вызова метода countDown(). При вызове метода
await() каким-либо потоком, он переходит в состояние ожидания момента
достижения счетчиком значения 0. Есть перегруженный метод
await(long timeout, TimeUnit unit), позволяющий организовать ожидание не дольше, чем в течение заданного интервала. Есть также метод getCount(),
позволяющий получить текущее значение счетчика.
В отличие от класса CyclicBarrier экземпляры этого класса одноразовые.
На практике данный класс удобно использовать для координации момента начала и окончания определенного числа потоков:
•можно сделать так, чтобы исполнение заданного числа потоков начиналось в один и тот же момент времени;
•можно отследить момент окончания заданного числа потоков.

java.util.concurrent Синхронизаторы.
Защелка (2)
class Master { // ...
int threadsCount = … ; // определение количества потоков Worker void masterMain( ) throws InterruptedException {
CountDownLatch startLatch = new CountDownLatch( 1 ); CountDownLatch readyLatch = new CountDownLatch( threadsCount );
for( int i = 0; i < threadsCount; ++i ) |
// создание и запуск потоков |
new Thread( new Worker( startLatch, readyLatch ) ).start( ); |
|
doSomething( ); |
// делается что-то |
startLatch.countDown( ); |
// фактический запуск |
doSomethingYet( ); |
// делается что-то еще |
readyLatch.await( ); // ожидание момента завершения всех потоков
}
// …
}

java.util.concurrent Синхронизаторы.
Защелка (3)
class Worker implements Runnable { private final CountDownLatch starting; private final CountDownLatch finishing;
Worker( CountDownLatch starting, CountDownLatch finishing ) { // конструктор this.starting = starting;
this.finishing = finishing;
} |
|
public void run( ) { |
|
try { |
|
starting.await(); |
// ожидание разрешения работать |
doWork(); |
// выполнение работы |
finishing.countDown(); |
// отметка, что поток завершился |
} catch ( InterruptedException ex ) {
}
return;
}
void doWork() { ... }
}

java.util.concurrent.atomic Классы с атомарными
операциями
Подпакет java.util.concurrent.atomic содержит несколько классов, предоставляющих атомарные операции:
AtomicBoolean
AtomicInteger
AtomicIntegerArray
AtomicIntegerFieldUpdater
AtomicLong
AtomicLongArray
AtomicLongFieldUpdater
AtomicMarkableReference
AtomicReference
AtomicReferenceArray
AtomicReferenceFieldUpdater
AtomicStampedReference

java.util.concurrent.atomic Основные методы атомарных классов (1)
|
У всех (кроме *Reference): |
|
boolean |
compareAndSet( |
сравнить текущее значение с expect, если совпадают – |
|
* expect, * update ) атомарно заменить текущее на update и вернуть true, |
|
|
|
иначе – вернуть false |
* |
get() |
вернуть текущее значение |
* |
getAndSet( * |
атомарно заменить значение на newValue, вернуть |
|
newValue) |
предыдущее значение |
void |
lazySet( * newValue ) |
На процессорах x86 практически ничем не отличается |
|
|
от просто set, но использовать можно, только тщательно |
|
|
разобравшись в отличии от метода set |
void |
set( * newValue ) |
атомарно заменить значение на newValue |
boolean weakCompareAndSet На процессорах x86 практически ничем не отличается ( * expect, * update ) от просто compareAndSet, но использовать можно,
только тщательно разобравшись в особенностях