Объектно-ориентированное программирование
План на семестр
План лекции
Проблемы однопоточного подхода
Многопоточное программирование
Квантование времени (Time-Slicing)
Поток в Java
Влияние многопоточности на память
Особенности многопоточности
Создение потоков в Java
Создание потока через расширение класса Thread
Создание потока через реализацию интерфейса Runnable
Создание потока через реализацию интерфейса Runnable
Особенности реализации интерфейса Runnable
Свойства потоков
Состояния потока
Состояния потоков
Состояния потока
Управление потокам
Метод Join
Прерывание потоков
Демон-потоки (Daemons)
Группы потоков (ThreadGroup)
Создание группы потоков
Операции в группе потоков
Спасибо за внимание!
1.78M
Category: programmingprogramming

L_8_Multithreading

1. Объектно-ориентированное программирование

Peter the Great St.Petersburg
Polytechnic University
Объектно-ориентированное
программирование

2. План на семестр

Многопоточное программирование
Модули и сборка проектов
Тестирование
2

3. План лекции

Многопоточное программирование
Модель потоков исполнения
Создание потоков в Java
Свойства и состояния потоков
Управление потоками
3

4. Проблемы однопоточного подхода

Монопольный захват задачей процессорного
времени
Смешение логически несвязанных фрагментов
кода
4

5. Многопоточное программирование

Последовательно выполняющиеся инструкции
составляют поток
Потоки выполняются независимо
Потоки могут взаимодействовать друг с другом
В многоядерной системе поток монопольно
занимает одно ядро
5

6. Квантование времени (Time-Slicing)

Время разделяется на интервалы (кванты времени)
Во время одного кванта обрабатывается один поток
команд
Решение о выборе потока принимается до начала
интервала
Переключения между потоками с высокой частотой
T1
T2
T3
T4
T3
T4
Время
6

7. Поток в Java

Java поток != поток в ОС.
В JVM есть свой планировщик потоков, который не
зависит от планировщика ОС.
В Java есть два вида потоков:
Потоки демоны (deamon threads) – не мешают завершению
программы
Пользовательские потоки (user threads) – пока хоть один
пользовательский поток есть, программа работает
Планировщик потоков в Java поддерживает
приоритетность
7

8. Влияние многопоточности на память

Каждый поток имеет свой стэк вызовов (stack)
Все потоки использую одну общую кучу (heap)
8

9. Особенности многопоточности

Простота выделения подзадач
Более гибкое управление выполнением задач
Более медленное выполнение
Выигрыш в скорости выполнения при разделении
задач по используемым ресурсам
Выигрыш в скорости выполнения на многоядерных
системах
Недетерминизм при выполнении
9

10. Создение потоков в Java

Многопоточная система в Java построена на основе
класса Thread
Дополняет класс Thread интерфейс Runnable
Два способа создания потока:
Расширить класс Thread
java.lang.Thread – класс потока. Позволяет создавать потоки
и производить операции с ними.
Реализовать интерфейс Runnable
java.lang.Runnable – интерфейс для сущности, которую
можно выполнить. Содержит единственный метод public void
run() . В нем должна содержаться задача, которую будет
выполнять поток
10

11. Создание потока через расширение класса Thread

Расширение и описание класса Thread
public class ИмяКласса extends Thread {
public void run() {
// Действия, выполняемые потоком
}
}
Запуск потока
ИмяКласса t = new ИмяКласса();
t.start(); // именно start(), а не run() !!!
11

12. Создание потока через реализацию интерфейса Runnable

Реализуем интерфейс Runnable
public class ИмяКласса implements Runnable {
public void run() {
// Действия, выполняемые потоком
}
}
Запуск потока
Runnable r = new ИмяКласса(); // Это ещё не поток
Thread t = new Thread(r); // А вот это уже поток
t.start();
12

13. Создание потока через реализацию интерфейса Runnable

Конструктор Thread(Runnable runnable, String name)
– создаёт поток с указанием его имени
Методы setName(String name) getName() позволяют
задать и получить имя для существующего потока
13

14. Особенности реализации интерфейса Runnable

Возможность создать класс, описывающий тело потока
и наследующий от класса, отличного от Thread
Объект вашего класса не является объектом потока
Невозможно использовать напрямую методы класса
Thread
Можно получить ссылку на объект текущего потока с
помощью статического метода currentThread()
класса Thread
14

15. Свойства потоков

Любой поток обладает следующими свойствами:
long id – идентификатор потока
String name – имя
int priority – приоритет. Чем он больше, тем больше
процессорного времени потоку будут стараться
давать.
boolean daemon – является ли поток демоном
Свойства id и deamon не могут меняться после его
запуска!!!
15

16. Состояния потока

State
Thread.State
Текущее состояние (NEW,
RUNNABLE, BLOCKED,
WAITING, TIMED_WAITING,
TERMINATED)
Alive
boolean
Жив ли поток (запущен и не
завершён)
isAlive()
Interrupted
boolean
Был ли запрос на прерывание
isInterrupted(),
interrupted()
getState()
int getState() и boolean isAlive() – методы получения
состояние потока
16

17. Состояния потоков

NEW (Создан)
Thread thread = new Thread(() -> {});
// thread находится в состоянии NEW
RUNNABLE (Готов к выполнению)
thread.start();
// thread переходит в состояние RUNNABLE
BLOCKED (Заблокирован)
synchronized (lock) {
// Поток может быть в состоянии BLOCKED, если другой поток удерживает lock
}
WAITING (Ожидание)
synchronized (lock) {
lock.wait(); // Поток переходит в состояние WAITING
}
TIMED_WAITING (Ожидание с таймаутом)
Thread.sleep(1000); // Поток переходит в состояние TIMED_WAITING
TERMINATED (Завершен)
thread.start();
thread.join(); // Ожидание завершения потока
// После завершения thread находится в состоянии TERMINATED
17

18. Состояния потока

New – созданный поток до момента пока его
запустили
Runnable – запущенный методом start() поток
ожидающий выделения ему процессорного
времени или исполняющийся поток, которому
выделено процессорное время
Waiting – поток заблокирован или чего-то ждёт
(условие, таймер и т.д.)
Dead – поток завершил свои задачи
RUNNABLE
18

19. Управление потокам

void start()
Запускает выполнение потока
void join()
Останавливает выполнение текущего потока до завершения
потока, у объекта которого был вызван метод
static void sleep(long millis)
Останавливает выполнение текущего потока как минимум на
millis миллисекунд
static void yield()
Приостанавливает выполнение текущего потока, предоставляет
возможность выполнять другие потоки
19

20. Метод Join

Как работает join()?
• Метод join() принадлежит классу Thread.
• Если поток A вызывает join() для потока B, то поток
A будет ждать, пока поток B не завершится.
• Если поток B уже завершён, то join() возвращается
немедленно.
join() — ожидает завершения потока неограниченное
время.
join(long millis) — ожидает завершения потока в
течение указанного времени в миллисекундах.
join(long millis, int nanos) — ожидает завершения
потока в течение указанного времени в миллисекундах
и наносекундах.
20

21. Прерывание потоков

В Java нельзя принудительно завершить поток.
Можно только попросить его завершиться.
Метод
Кто вызывает
Что делает
Особенность
Поток A
Устанавливает флаг
прерывания целевому
потоку
Если поток в WAITING/
TIMED_WAITING —
бросает InterruptedExcep
tion и сбрасывает флаг
isInterrupted()
Любой
Проверяет флаг
прерывания целевого
потока
НЕ сбрасывает флаг
Thread.interrupte
d()
Текущий
поток
Проверяет флаг
прерывания текущего
потока
СБРАСЫВАЕТ флаг
(false после вызова)
interrupt()
21

22. Демон-потоки (Daemons)

Демон-потоки позволяют описывать фоновые процессы,
которые нужны только для обслуживания основных
потоков выполнения и не могут существовать без них
Уничтожаются виртуальной машиной, если в группе не
осталось не-демон потоков
void setDaemon(boolean on)
Устанавливает вид потока
Вызывается до запуска потока
boolean isDaemon()
Возвращает вид потока:
true – демон, false – обычный
22

23. Группы потоков (ThreadGroup)

Каждый поток находится в
группе
Группы потоков образуют
дерево, корнем служит
начальная группа
TG1
TG2
T3
TG3
TG4
T4
Поток не имеет доступа к
информации о родительской
группе
Изменение параметров и
состояния группы влияет на все
входящие в нее потоки
T1
T2
T6
T5
TG1
TG2
TG3
TG4
23

24. Создание группы потоков

Создание группы
//Без явного указания родительской группы
ThreadGroup group1 = new ThreadGroup("Group1");
//С явным указанием родительской группы
ThreadGroup group2 = new ThreadGroup(group1, "Group2");
Создание потока
//Без явного указания группы
MyThread t1 = new MyThread("Thread1");
//С явным указанием группы
MyThread t2 = new MyThread(group2, "Thread2");
24

25. Операции в группе потоков

int activeCount()
Возвращает оценку количества потоков
int enumerate(Thread[] list)
Копирует в массив активные потоки
int activeGroupCount()
Возвращает оценку количества подгрупп
int enumerate(ThreadGroup[] list)
Копирует в массив активные подгруппы
void interrupt()
Прерывает выполнение всех потоков в группе
25

26. Спасибо за внимание!

Санкт-Петербургский политехнический
университет Петра Великого
Спасибо за внимание!
English     Русский Rules