
- •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)
К синхронизаторам можно отнести различного рода структуры, которые отвечают за координацию работы потоков. Некоторые такие структуры реализованы в пакете java.util.concurrency:
Семафоры
Барьеры
Обменники
Защелки
Считающим семафором называют целочисленную переменную, выполняющую те же функции, что и флаг блокировки. Однако в отличие от последнего она может принимать кроме 0 и 1 ( true/false) и другие целые положительные значения.
Семафоры используются для ограничения числа потоков, которые используют некий ресурс. Максимально возможное значение семафора, понимаемое как количество потоков, которые одновременно могут получить доступ к ресурсу, задается аргументом конструктора. Вторым (необязательным) аргументом может быть булево значение, определяющее "справедливость" захвата ресурса ожидающими потоками. При реализации справедливой политики ресурс будет отдан тому потоку, который первым попытался его захватить. За справедливость приходится платить довольно большими временными затратами, поэтому обычно реализуется несправедливый вариант.

java.util.concurrent
Синхронизаторы. Семафоры (2)
Основные методы класса java.util.concurrent.Semaphore:
void |
acquire( ) |
Получить доступ к ресурсу. Поток блокируется, пока |
|
|
не доступ не будет получен или пока его не прервут. |
void |
acquire( int permits ) |
Получить permits доступов к ресурсу. Поток |
|
|
блокируется, пока не доступ не будет получен или |
|
|
пока его не прервут. |
void |
acquireUninterruptibly() |
Получить доступ к ресурсу с запретом прерывания. |
void |
acquireUninterruptibly( i |
Получить permits доступов к ресурсу с запретом |
|
nt permits ) |
прерывания. |
int |
availablePermits( ) |
Возвращает количество свободных доступов |
int |
drainPermits( ) |
Получить все свободные доступы |
protected |
getQueuedThreads( ) |
Возвращает коллекцию потоков, ожидающих |
Collection<Thread> |
|
получения доступа |
int |
getQueueLength( ) |
Возвращает количество потоков, ожидающих |
|
|
получения доступа |
boolean |
hasQueuedThreads( ) |
Возвращает true, если есть хотя бы один ожидающий |
|
|
поток |

java.util.concurrent
Синхронизаторы. Семафоры (3)
boolean |
isFair( ) |
Возвращает true, если для семафора установлена |
|
|
справедливая политика |
protected |
reducePermits( int reduction ) |
Уменьшить количество доступов на указанную величину |
void |
|
|
void |
release( ) |
Освободить один доступ |
void |
release( int permits ) |
Освободить указанное количество доступов |
boolean |
tryAcquire( ) |
Попытаться получить один доступ. В случае успеха |
|
|
возвращается true. |
boolean |
tryAcquire( int permits ) |
Попытаться получить указанное количество доступов. В |
|
|
случае успеха возвращается true. |
boolean |
tryAcquire( int permits, long |
Попытаться получить указанное количество доступов в |
|
timeout, TimeUnit unit ) |
течение заданного интервала времени. В случае успеха (и |
|
|
если поток не был прерван) возвращается true. |
boolean |
tryAcquire( long timeout, |
Попытаться получить один доступ в течение заданного |
|
TimeUnit unit ) |
интервала времени. В случае успеха (и если поток не был |
|
|
прерван) возвращается true. |

java.util.concurrent
Синхронизаторы. Семафоры (4)
Задача "писатель-читатель", в которой для передачи данных используется пул буферов: interface Buffer {
void markAsUsed( ); boolean markedAsUsed( );
}
…
private final Semaphore buffers = new Semaphore( MAX_BUFFERS, true );
…
public Buffer getBuffer() throws InterruptedException { buffers.acquire();
Buffer buffer = getNextAvailableBuffer(); buffer.markAsUsed( );
return buffer;
}
public void retBuffer(Buffer buf) {
if (buf.markedAsUsed( ) == false) buffers.release( );
putBufferToQueue( buf );
}
…

java.util.concurrent
Синхронизаторы. Барьеры (1)
Барьер – это средство синхронизации, которое используется для того, чтобы некоторое множество потоков ожидало друг друга в некоторой точке программы, называемой обычно точкой синхронизации.
В тот момент, когда все потоки достигают точки синхронизации, они разблокируются и могут продолжать выполнение.
На практике барьеры обычно используются для сбора результатов выполнения некоторой распараллеленной задачи. В качестве примера можно рассмотреть задачу умножения матриц. При распараллеливании данной задачи каждому потоку будет поручено умножение определенных строк на определенные столбцы. В точке синхронизации все полученные результаты собираются из потоков и в одно из них строится результирующая матрица.
В пакете java.util.concurrent для реализации барьерной синхронизации используется класс CyclicBarrier. Конструкторы этого класса получают
количество потоков, которые должны достичь точки синхронизации и, опционально, экземпляр интерфейса Runnable, который должен быть
исполнен в момент достижения этой точки всеми потоками:
CyclicBarrier( int parties );
CyclicBarrier( int parties, Runnable barrierAction );

java.util.concurrent
Синхронизаторы. Барьеры (2)
Методы класса java.util.concurrent.CyclicBarrier:
int |
await( ) |
Ожидание, пока заданное в конструкторе количество потоков |
|
|
выполнит вызов этого метода. |
int |
await( long timeout, |
Ожидание, пока заданное в конструкторе количество потоков |
|
TimeUnit unit ) |
выполнит вызов этого метода или пока не закончится заданный |
|
|
тайм-аут. |
int |
getNumberWaiting( ) |
Возвращает количество ожидающих потоков. |
int |
getParties( ) |
Возвращает количество потоков, требуемых для преодоления |
|
|
этого барьера (установленное при создании экземпляра). |
boolean |
isBroken( ) |
Возвращает true, если хотя бы один поток прерван или ушел из |
|
|
ожидания по тайм-ауту. |
void |
reset( ) |
Сброс барьера в исходное состояние. |
Нужно отметить, что в момент срабатывания барьера экземпляр класса восстанавливает начальное состояние и может отрабатывать следующие parties срабатываний потоков.

java.util.concurrent Синхронизаторы.
Барьеры (3)
В этой программе параллельно вычисляются суммы элементов строк матрицы:
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier;
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
Синхронизаторы. Барьеры (4)
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
Синхронизаторы. Барьеры (5)
public static void main( String args[ ] ) { |
|
// здесь объявления |
|
final int rows = matrix.length; |
|
results = new int[ rows ]; |
|
Runnable merger = new Runnable( ) { |
// внутренний класс |
public void run() { |
// сложение сумм по строкам |
int sum = 0; |
|
for ( int i = 0; i < rows; i++ ) |
|
sum += results[ i ]; |
|
synchronized( flag ) { |
// извещение основного потока |
flag.notifyAll( ); |
|
flag = true; |
|
}
System.out.println("Сумма элементов матрицы равна: " + sum);
}
};

java.util.concurrent Синхронизаторы.
Барьеры (6)
CyclicBarrier barrier = new CyclicBarrier( rows, merger ); for ( int i = 0; i < rows; i++ ) { // запуск всех сумматоров
new Summator( barrier, i ).start( );
} |
|
|
System.out.println( "Ожидание..." ); |
|
|
Сумма элементов строки 1 равна: 4 (9) |
||
synchronized( flag ) { |
||
while( !flag ){ |
Сумма элементов строки 2 равна: 9 (10) |
|
try { |
Сумма элементов строки 0 равна: 102 (8) |
|
Сумма элементов строки 4 равна: 25 (12) |
||
flag.wait( ); |
||
Ожидание (1) |
||
} catch( InterruptedException e ) { |
||
Сумма элементов строки 3 равна: 16 (11) |
||
return; |
Сумма элементов строки 5 равна: 612 (13) |
|
} |
Сумма элементов матрицы равна: 768 (13) |
|
} |
Вычисления закончены (1) |
}
System.out.println( "Вычисления закончены" );
}
}
В скобках показаны идентификаторы потоков.