
- •Многопоточное программирование
- •Цели занятия
- •Понятие многопоточности
- •Реализация многопоточности
- •Реализация многопоточности
- •Особенности многопоточности
- •Использование класса Thread
- •Использование класса Thread
- •Использование класса Thread
- •Использование интерфейса
- •Использование интерфейса
- •Управление потоками
- •Нерекомендуемые действия над
- •Группы потоков
- •Группы потоков
- •Операции в группе потоков
- •Приоритеты потоков
- •Приоритеты потоков
- •Демон-потоки
- •Демон-группы потоков
- •Совместное использование
- •Совместное использование
- •Совместное использование
- •Совместное использование
- •Характерные ошибки
- •volatile
- •volatile
- •Специальные методы класса
- •Особенности использования
- •Прерывание потока
- •Пример
- •Пример
- •Пример
- •java.util.concurrent
- •java.util.concurrent
- •java.util.concurrent.locks
- •Lock Objects
- •ReentrantLock
- •Пример ReentrantLock
- •ReadWriteLock
- •Пример ReadWriteLock
- •Исполнители (Executors)
- •Интерфейсы исполнителей
- •Интерфейс Executor
- •Интерфейс
- •Thread Pools
- •Thread Pools
- •Executors
- •Пример ExecutorService
- •Пример ExecutorService.invokeAll()
- •InterruptedException
- •Прерывание потока
- •Пример InterruptedException
- •Пример восстановления статуса
- •Пример отменяемой задачи
- •Литература

Многопоточное программирование
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |

Цели занятия
2 Изучить:
•Проблемы однопоточного подхода
•Понятие и особенности многопоточности
•Использование класса Thread и интерфейса Runnable
•Управление потоками, нерекомендуемые действия над потоками
•Группы потоков, операции в группе потоков
•Приоритеты потоков
•Демон-потоки, демон-группы потоков
•Совместное использование ресурсов, механизм блокировки объекта, ключевое слово synchronized
•volatile
•Специальные методы класса Object и их особенности
•java.util.concurrent
•InterruptedException
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |

Понятие многопоточности
3• Последовательность операций, выполняемых программой по одной в каждый момент времени, называют потоком (или нитью – thread)
•Проблемы однопоточного подхода
Монопольный захват задачей процессорного времени
Смешение логически несвязанных фрагментов кода
Попытка их разделения приводит к возникновению в программе новых систем
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |

Реализация многопоточности
4• Реализацию многопоточной архитектуры проще всего представить себе для системы, в которой есть несколько центральных вычислительных процессоров
•В этом случае для каждого из них можно выделить задачу, которую он будет выполнять
•В результате несколько задач будут обслуживаться одновременно
•Однако возникает вопрос – каким же тогда образом обеспечивается многопоточность в системах с одним центральным процессором, который в принципе выполняет лишь одно вычисление в один момент времени?
•В таких системах применяется процедура квантования времени – время разделяется на небольшие интервалы (кванты времени)
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |

Реализация многопоточности
5• Во время одного кванта обрабатывается один поток команд
•Перед началом каждого интервала принимается решение, какой именно поток выполнения будет обрабатываться на протяжении этого кванта времени
•За счет частого переключения между задачами эмулируется многопоточная архитектура, т.е. создается иллюзия одновременности выполнения
•На самом деле, как правило, и для многопроцессорных систем применяется процедура квантования времени, так как даже в мощных серверах приложений процессоров не так много, а потоков исполнения запускается, как правило, гораздо больше
•Т.о. в многопроцессорной системе поток не занимает монопольно один процессор
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |

Особенности многопоточности
6 • Потоки выполняются условно независимо
•Потоки могут взаимодействовать друг с другом
•Простота выделения подзадач
•Более гибкое управление выполнением задач
•Более медленное выполнение
•Выигрыш в скорости выполнения при разделении задач по используемым ресурсам
•Недетерминизм при выполнении
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |

Использование класса Thread
7• Поток выполнения в Java представляется
экземпляром класса Thread
•Для того, чтобы написать свой поток исполнения, необходимо наследоваться от этого класса и переопределить метод run()
•Стандартная реализация метода run() не предполагает выполнения каких бы то ни было действий
•Объявление:
public class MyThread extends Thread { public void run() {
// Действия, выполняемые потоком
}}
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |

Использование класса Thread
8• Метод run() содержит действия, которые должны исполняться в новом потоке исполнения
•Чтобы запустить его, необходимо создать экземпляр класса-наследника, и вызвать унаследованный метод start(), который сообщает виртуальной машине, что необходимо запустить новый поток исполнения и начать в нем исполнять метод run()
•Запуск:
MyThread t = new MyThread(); t.start();
•Вызов start() для каждого потока может быть осуществлен только один раз – повторное обращение приводит к выбрасыванию исключения типа
IllegalThreadsStateException
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |

Использование класса Thread
9• Потоку разрешено присвоить имя – либо с помощью аргумента String, переданного конструктору, либо посредством вызова метода setName(), текущее значение имени потока можно получить с помощью метода getName()
•Имена потоков служат только для удобства программиста (исполняющей системой они не используются), но поток должен обладать именем, и если оно не задано, исполняющая система генерирует имена в соответствии с неким простым правилом, например, thread_1, thread_2 и т.д.
•Ссылку на объект Thread текущего выполняемого потока можно получить с помощью статического метода Thread.currentThread()
•Во время работы программы текущий поток существует всегда, даже если вы не создавали потоки явно – метод main() активизируется с помощью потока, создаваемого исполняющей системой
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |

Использование интерфейса
Runnable
10• Описанный подход обладает одним недостатком: поскольку в Java отсутствует множественное наследование, требование наследоваться от Thread может привести к конфликту
•Поэтому предлагается более простой способ создать свой поток исполнения
•Достаточно реализовать интерфейс Runnable, в котором объявлен только один метод – уже знакомый void run()
•Объявление:
public class MyThread implements Runnable { public void run() {
// Действия, выполняемые потоком
}}
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |