Участок исполняемого кода программы, в котором производится доступ к общему ресурсу (данным или устройству), который не должен быть одновременно использован более чем одним потоком исполнения. Например, запись в файл, не должна производиться одновременно несколькими потоками.
Объект, ограничивающий количество потоков, которые могут войти в заданный участок кода.
Внутри него есть счетчик и изначально в нем выставленно некое значение n.
init(n)
счетчик = n
У этого счетчика есть 2 метода enter() и leave().
enter() - ждать пока счетчик станет больше 0, после этого уменьшить на единицу
leave() - увеличить счетчик на единицу
Простейший двоичный семафор, который может находиться в одном из двух состояний - отмеченном или неотмеченном (0 или 1). Это основа организации Critical Section.
Блокировка - это механизм синхронизации, позволяющий обеспечить исключительный доступ к разделяемому ресурсу между несколькими потоками. С помощью mutex'a подходя к некому участку кода проверяем можем ли мы туда зайти.
Мягкая блокировка - каждый поток пытается получить блокировку перед доступом к соответсвтующему разделяемому ресурсу
Обязательная блокировка - попытка несанкционированного доступа к заблокированному ресурсу будет прервана через создание исключения
Аппаратная поддержка: compare-and-swap
Механизм взаимодействия и синхронизации процессов. Высокоуровневая конструкция, которая состоит из mutex'a, блокировки и массива ожидающих очереди потоков.
У монитора должен быть механизм остановки потока и сигнализации о доступности продолжения работы.
Это применение шаблона разделяющего создание сущности и ее использования. Разделяет создание Runnable и способ запуска run().
Executor нужен для тгго чтобы запустить на исполнение то что вы написали в Runnable, каким то образом позвать run().
Самый простой executor, который выполняет Runnable в том же потоке:
public class DirectExecutor implements Executor {
@Override
public void execute(Runnable r) {
r.run();
}
}Либо executor, который выполняет Runnable в отдельном потоке:
public class ThreadPerTaskExecutor implements Executor {
@Override
public void execute(Runnable r) {
new Thread(r).start();
}
}Runnable выполняет действия но не возвращает результат. Callable выполняет действие и возвращает результат.
TaskExtendedRunnable task = new TaskExtendedRunnable();
Thread t = new Thread(task);
t.start();
t.join();
String value = task.getSavedValue();ExecutorService pool = Executors.newFixedThreadPool(1);
Callable<Integer> callable = new TaskExtendedCallable();
Future<Integer> future = pool.submit(callable);
Integer value = future.get(); Пулл потоков - Объект предоставляющий потоки.
ExecutorService pool = Executors.newFixedThreadPool(1);
Callable<Integer> callable = new TaskExtendedCallable();
Future<Integer> future = pool.submit(callable);Обертка над value, будет получено в будущем.
Future<Integer> future = pool.submit(callable);
future.get(); //блокировка до получения результата