Слайд 1Многопоточное программирование на Java
Java Advanced
Слайд 2Java Advanced / Многопоточное программирование. Средства языка Java
Содержание
Потоки
Блокировки (синхронизация)
Мониторы и условия
Модель
памяти Java
Примеры
Заключение
Слайд 4Java Advanced / Многопоточное программирование. Средства языка Java
Создание потоков
Класс Thread –
поток
Позволяет создавать потоки и производить операции с ними
Интерфейс Runnable – сущность, которая может быть запущена
public void run();
Слайд 5Java Advanced / Многопоточное программирование. Средства языка Java
Создание потока (Runnable)
Пример кода
//
Создание потока
Thread t = new Thread(new Runnable() {
public void run() {
System.out.println("Hello");
}
});
// Запуск потока
t.start();
Слайд 6Java Advanced / Многопоточное программирование. Средства языка Java
Создание потока (Thread)
Не рекомендуется
использовать
Пример кода
// Создание потока
Thread t = new Thread() {
public void run() {
System.out.println("Hello");
}
};
// Запуск потока
t.start();
Слайд 7Java Advanced / Многопоточное программирование. Средства языка Java
Состояния потока
Состояние потока возвращается
методами int getState() и boolean isAlive() класса Thread
Слайд 8Java Advanced / Многопоточное программирование. Средства языка Java
Свойства потока
Основные свойства
id –
идентификатор потока
name – имя потока
priority – приоритет
daemon – поток-демон
Свойства потока не могут изменяться после запуска
Слайд 9Java Advanced / Многопоточное программирование. Средства языка Java
Взаимодействие потоков
Создание потока
Запуск потока
Ожидание
окончания потока
Прерывание потока
Слайд 10Java Advanced / Многопоточное программирование. Средства языка Java
Ожидание окончания потока
Методы класса
Thread
join() – ожидать до завершения
join(long millis) – ожидать до завершения или истечения millis миллисекунд
join(long millis, long nanos) – ожидать до завершения или истечения millis миллисекунд и nanos миллисекунд
Все методы ожидания кидают InterruptedExcepton
Слайд 11Java Advanced / Многопоточное программирование. Средства языка Java
Прерывание потока
Методы класса Thread
interrupt()
– установить флаг прерывания
isInterrupted() – проверить флаг прерывания
interrupted() – проверить и сбросить флаг прерывания
Методы, которые ожидают в процессе выполнения должны бросать InterruptedException
Слайд 12Java Advanced / Многопоточное программирование. Средства языка Java
Дополнительные методы
Приостановка выполнения
sleep(time) –
приостановить поток на время
yield() – позволить выполниться другим потокам
Получение текущего потока
currentThread()
Слайд 13Блокировки (синхронизация)
Часть 2
Слайд 14Java Advanced / Многопоточное программирование. Средства языка Java
Общий случай
Любой объект может
служить блокировкой
Снятие блокировки производится автоматически
Синтаксис
synchronized (o) { // Получение блокировки
…
} // Снятие блокировки
Слайд 15Java Advanced / Многопоточное программирование. Средства языка Java
Методы экземпляра
Метод экземпляра может
быть объявлен синхронизованным
public synchronized int getValue() { … }
Эквивалентно
public int getValue() {
synchronized (this) { … }
}
Слайд 16Java Advanced / Многопоточное программирование. Средства языка Java
Производитель-потребитель (1)
Класс данных
class Data
{
private Object data;
public void set(Object data) { … }
public Object get() { … }
}
Слайд 17Java Advanced / Многопоточное программирование. Средства языка Java
Производитель-потребитель (2)
Установка значения
public
void set(Object data) {
while (true) {
synchronized (this) {
if (data == null) {
this.data = data;
break;
}
}
}
}
Слайд 18Java Advanced / Многопоточное программирование. Средства языка Java
Производитель-потребитель (3)
Получение значения
public
Object get() {
while (true) {
synchronized (this) {
if (data != null) {
Object d = data; data = null;
return d;
}
}
}
}
Слайд 20Java Advanced / Многопоточное программирование. Средства языка Java
Монитор
Любой объект может быть
монитором
Для взаимодействия с монитором поток должен иметь блокировку на него
Методы монитора
wait(time?) – ожидание монитора
notify() – извещение одного из ждущих потоков
notifyAll() – извещение всех ждущих потоков
Слайд 21Java Advanced / Многопоточное программирование. Средства языка Java
Мониторы и блокировки
При ожидании
монитора блокировка с него снимается
При извещении поток не получает управления пока не может получить блокировку обратно
Псевдокод
monitor.unlock()
monitor.await()
monitor.lock()
Слайд 22Java Advanced / Многопоточное программирование. Средства языка Java
Производитель-потребитель (2)
Установка значения
public synchronized
void set(Object data)
throws InterruptedException
{
while (data != null) wait();
this.data = data;
notify();
}
Слайд 23Java Advanced / Многопоточное программирование. Средства языка Java
Производитель-потребитель (3)
Получение значения
public synchronized
Object get()
throws InterruptedException
{
while (data == null) wait();
Object d = data;
data = null;
notify();
return d;
}
Слайд 25Java Advanced / Многопоточное программирование. Средства языка Java
Основные свойства
Атомарность
Видимость
Упорядоченность
Слайд 26Java Advanced / Многопоточное программирование. Средства языка Java
Атомарность
Атомарная операция выполняется как
единое целое
Операции над всеми типами кроме long и double являются атомарными
Слайд 27Java Advanced / Многопоточное программирование. Средства языка Java
Пример
int a = 0;
long
b = 0;
a = 1;
b = -1;
Возможные значения a
0
1
Возможные значения b
0
-1
0xffffffff00000000
0x00000000ffffffff
…
Слайд 28Java Advanced / Многопоточное программирование. Средства языка Java
Видимость
Изменения произведенные потоком 1
видимы потоком 2
Видимость гарантируется в следующих случаях
После изменений поток 1 освободил блокировку, которую захватил поток 2
После изменения поток 1 создал поток 2
Поток 2 дождался окончания потока 1
При неправильной синхронизации изменения могут быть видимы в произвольном порядке
Слайд 29Java Advanced / Многопоточное программирование. Средства языка Java
Пример
int a = 0;
int
b = 0;
a = 1;
b = 2;
Возможные значения пары а, b
0, 0
1, 0
1, 2
0, 2
Слайд 30Java Advanced / Многопоточное программирование. Средства языка Java
Упорядоченность
Программы выполняются как если
бы они были написаны последовательно
С точки зрения других потоков выполнение программы может производиться в произвольном порядке
Слайд 31Java Advanced / Многопоточное программирование. Средства языка Java
Пример
int a = 0;
a
= 1;
a = 2;
Возможные последовательности значений а
0, 0
0, 1
0, 2
1, 2
2, 0
2, 1
…
Слайд 32Java Advanced / Многопоточное программирование. Средства языка Java
Volatile-переменные
Операции с volatile-переменными всегда
атомарны
При чтение значения volatile-переменной оно всегда читается из общей памяти
При записи значения volatile-переменной оно всегда записывается в общую память
Если volatile-ссылка изменилась, то данные доступные по ней могли не измениться
Слайд 33Java Advanced / Многопоточное программирование. Средства языка Java
Пример
volatile List l =
null;
t1() {
List l = new ArrayList();
l.add(new Object());
this.l = l;
}
Object t2() {
while (l != null) {
return l.get(0);
}
}
Слайд 34Java Advanced / Многопоточное программирование. Средства языка Java
Выводы
При отсутствии правильной синхронизации
потоки могут увидеть практически что угодно
Слайд 36Java Advanced / Многопоточное программирование. Средства языка Java
Барьер
public await(Barrier that) {
// 0
synchronized (this) { // 1
this.generation++; // 2
this.notify(); // 3
} // 4
synchronized (that) { // 5
while (this.generation != that.generation) { // 6
that.wait(); // unlock 7, await 8, lock 9
} // 10
} // 11
}
Слайд 37Java Advanced / Многопоточное программирование. Средства языка Java
Диаграмма переходов для барьера
Слайд 38Java Advanced / Многопоточное программирование. Средства языка Java
Гарантированный deadlock
public void run()
{ // 0
synchronized (o1) { // 1
o1.notifyAll(); // 2
synchronized (o2) { // 3
try {
o2.wait(); // unlock 4, await 5, lock 6
} catch (InterruptedException e) {}
} // 7
} // 8
}
Слайд 39Java Advanced / Многопоточное программирование. Средства языка Java
Диаграмма переходов для deadlock
Слайд 41Java Advanced / Многопоточное программирование. Средства языка Java
Выводы
Программы должны быть хорошо
синхронизированы
Недосинхронизированные программы могут вести себя практически как угодно
Пересенхронизированные программы часто страдают deadlock’ами
Слайд 42Java Advanced / Многопоточное программирование. Средства языка Java
Ссылки
JLS. Threads and Locks
// http://java.sun.com/docs/books/jls/third_edition/html/memory.html
Threads: Doing Two or More Tasks At Once (Java Tutorial) // http://java.sun.com/docs/books/tutorial/essential/threads/index.html
Слайд 43Java Advanced / Многопоточное программирование. Средства языка Java
Вопросы