Uploaded by ersaismailov

Лекция Многопоточное программирование на Java

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