29
Язык программирования JAVA Лекция# 3 (Часть 3) Реализация многопоточности в Java Моисеенко Антон [email protected] СПГУАП Кафедра Информационно-Сетевых Технологий

Java Core. Lecture# 3. Part# 3. Multithreading

Embed Size (px)

Citation preview

Page 1: Java Core. Lecture# 3. Part# 3. Multithreading

Язык программирования JAVA

Лекция# 3 (Часть 3)Реализация многопоточности в Java

Моисеенко Антон[email protected]

СПГУАПКафедра Информационно-Сетевых Технологий

Page 2: Java Core. Lecture# 3. Part# 3. Multithreading

Содержание курса■ Что такое поток?■ Многопоточность в java■ Состояние потока■ Приоритет

■Класс java.lang.Thread■ Два способа создать поток■ Расширение класс Thread■ Реализация интерфейса Runnable■ Создание анонимного класса■ Класс java.lang.ThreadGroup■ Потоки и исключения■ Планировщик потоков■ Приоритет

■Остановка потока

Page 3: Java Core. Lecture# 3. Part# 3. Multithreading

Что такое поток?• Определение:

– последовательность выполняемых операций внутри программы.

• Для чего нужны потоки?– Одновременное исполнение действий.

Page 4: Java Core. Lecture# 3. Part# 3. Multithreading

Многопоточность в Java■ Каждое приложение на Java имеет по крайней мере

один пользовательский поток.■ С точки зрения программирования, каждая

программа начинается с выполнения одного потока – потока Main.

■ Main поток может создавать и запускать другие потоки.

Page 5: Java Core. Lecture# 3. Part# 3. Multithreading

Состояния потока• New – создан, но не запущен.• Ready-to-run – готов к работе.

– Поток помещается в очередь, ожидающую доступа к ресурсам ЦП.

• Running – активно использует ресурсы CPU.• Blocked – ожидает ресурсов или событий.• Waiting, Sleeping – поток перестал использовать ЦП.

– Самостоятельно или был принудительно снят с исполнения.

Page 6: Java Core. Lecture# 3. Part# 3. Multithreading

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

Page 7: Java Core. Lecture# 3. Part# 3. Multithreading

Приоритет• Позволяет определить порядок использования

ресурсов ЦП.• Определение.

• Целое число от 1 до 10.• Чем больше приоритет потока, тем у него больше

шансов получить управление.

Page 8: Java Core. Lecture# 3. Part# 3. Multithreading

Класс java.lang.Thread■ Данный класс предоставляет абстракцию,

позволяющую выполнять инструкции языка Java в отдельном потоке.

■ Имеет следующие конструкторы.

Thread() Создает новый класс.

Thread(String name) Создает новый именованный класс-поток.

Thread(Runnable target) Создает новый класс-поток на основе экземпляра Runnable, чей метод run() будет исполняться в отдельном потоке.

Thread(Runnable target, String name)

Создает новый именованный класс-поток на основе Runnable.

Page 9: Java Core. Lecture# 3. Part# 3. Multithreading

Класс java.lang.Thread (cont.)■ Имеет несколько публичных полей, отражающих

относительные приоритеты.

public final static int MAX_PRIORITY Максимальный приоритет (10).

public final static int MIN_PRIORITY Минимальный приоритет (1).

public final static int NORM_PRIORITY Обычный приоритет (5).

Page 10: Java Core. Lecture# 3. Part# 3. Multithreading

Класс java.lang.Thread (cont.)Среди методов класса можно выделить:public static Thread currentThread() Возвращает ссылку на активный в настоящее

время поток.

public final String getName() Возвращает имя потока.

public final String setName(String name) Устанавливает имя потока.

public void interrupt() Прерывает поток.

public int getPriority() Возвращает приоритет потока.

public final boolean isAlive() Определяет, работает ли поток.

Page 11: Java Core. Lecture# 3. Part# 3. Multithreading

Класс java.lang.Thread (cont.)public void run() Метод запускается в отдельном потоке.

public void start() Запускает выполнение метода run() в отдельном потоке.

public void join(Thread other)

Приостанавливает исполнение текущего потока до тех пор пока поток other не завершится.

public void stop() Завершает выполнение потока.

public void resume() Восстанавливает выполнение потока.

public void sleep(long delay) Приостанавливает выполнение потока на delay миллисекунд.

public void yield() Метод пробует отказаться от выполнения на ЦП в пользу других потоков.

Page 12: Java Core. Lecture# 3. Part# 3. Multithreading

Два способа создать поток■ Наследование от класса Thread.■ Реализация интерфейса Runnable.

Page 13: Java Core. Lecture# 3. Part# 3. Multithreading

Расширение класса Thread■ Наследник класса Thread

переопределяет метод run().■ Создается экземпляр подкласса.■ Вызов метода start() данного подкласса

запускает выполнение потока.○ Виртуальная машина начинает выполнение

потока вызовом метода run().

Page 14: Java Core. Lecture# 3. Part# 3. Multithreading

Две схемы запуска потока■ Конструктор подкласса класса Thread

не вызывает метод start().○ Нужно явно вызвать метод start() для

данного подкласса.■ Помещение вызова метода start() в

конструктор подкласса класса Thread.○ Создание экземпляра класса

автоматически запустит новый поток.

Page 15: Java Core. Lecture# 3. Part# 3. Multithreading

Пример создания потока (Thread)

class SimpleCombat extends Thread { public void run(){ //конкретные действия поединка takePosition(); fire(); } …}//запуск инструкций в новом потоке new SimpleCombat().start();

Page 16: Java Core. Lecture# 3. Part# 3. Multithreading

Интерфейс java.lang.Runnable

■ Интерфейс Runnable должен быть реализован классом, предназначенным для выполнения в отдельном потоке.

■ Класс должен реализовывать один метод run().○ Этот метод похож на метод main(String s[]).

■ Экземпляр класса должен быть передан конструктору класса Thread в качестве аргумента.

■ Запуск потока осуществляется методом start() класса Thread.

Page 17: Java Core. Lecture# 3. Part# 3. Multithreading

Две схемы запуска потока

■ Конструктор класса, реализующего интерфейс Runnable в своем конструкторе не вызывает метод start().○ Нужно явно вызвать метод start() для данного

класса.■ Помещение вызова метода start() в конструктор

класса, реализующего интерфейс Runnable.○ Создание экземпляра класса автоматически

запустит новый поток.

Page 18: Java Core. Lecture# 3. Part# 3. Multithreading

Пример создания потока (Runnable)

class SimpleCombat implements Runnable{ public void run(){ //конкретные действия поединка takePosition(); fire(); }}SimpleCombat combat = new SimpleCombat();new Thread(combat).start();

Page 19: Java Core. Lecture# 3. Part# 3. Multithreading

Наследование класса Thread и реализация интерфейса Runnable

■ Реализация интерфейса.○ Требует больше кода.

■ Реализация интерфейса.■ Создание класса Thread.

○ Еще можно наследоваться от другого класса.■ Наследование от класса Thread.

○ Проще в реализации.○ Класс больше не может никого расширять.

■ Если нет других ограничений, то выбор между двумя подходами – дело вкуса.

Page 20: Java Core. Lecture# 3. Part# 3. Multithreading

Создание анонимного класса

new Thread() { public void run(){ //код }}.start();

Page 21: Java Core. Lecture# 3. Part# 3. Multithreading

Класс java.lang.ThreadGroup

■ Потоки могут объединяться в группы○ Группы могут включать в себя другие группы.

■ Потоку разрешено получать информацию о своей группе.○ Запрещено о других группах и о более крупных

группах (являющихся надгруппами).■ Создается объект класса ThreadGroup и передается в

конструктор при создании объекта класса Thread.

Page 22: Java Core. Lecture# 3. Part# 3. Multithreading

Потоки и исключительные ситуации

■ Исключительная ситуация обрабатывается в следующем порядке○ в самом потоке○ дается запрос на обработчик

UncaughtExceptionHandler через метод Thread.getUncaughtExceptionHandler() и вызывается метод uncaughtException() этого обработчика

○ ThreadGroup выступает в качестве UncaughtExceptionHandler

○ делается запрос в обработчик по умолчанию Thread.getDefaultUncaughtExceptionHandler()

■ Если поток или группа потоков не обрабатывает исключение, то оно обрабатывается JVM.

Page 23: Java Core. Lecture# 3. Part# 3. Multithreading

Потоки и исключительные ситуации

class MyThread extends Thread { public void run() { throw new RuntimeException("xxx"); }}class CustomHandler implements Thread.UncaughtExceptionHandler { public void uncaughtException(Thread t, Throwable e) { System.out.println("custom " + e.getMessage()); }}public class Test { public static void main (String[] args) { MyThread thr = new MyThread(); thr.setUncaughtExceptionHandler(new CustomHandler()); thr.start(); }}

Page 24: Java Core. Lecture# 3. Part# 3. Multithreading

Планировщик потоков

Потоки соревнуются между собой за возможность быть исполненными. Этот класс стремится избавиться от соперника:

class Hero extends Thread { String name; //как зовут героя Hero enemy; //кто враг и кого атаковать public Combat(String name){ this.name = name; } public void assignEnemy(Hero enemy){ this.enemy = enemy;} public void run(){ for (int i=0;i<=10000;i++) System.out.println(name + “ hits “+ enemy ”+ i

+”times”);}

}

Page 25: Java Core. Lecture# 3. Part# 3. Multithreading

Планировщик потоков (cont.)

Перед началом поединка нужно создать персонажи, назначить соперников.

//создаем два персонажа:Hero batman = new Hero(“Batman”); Hero joker = new Hero(“Joker”); //назначаем соперников:batman.assignEnemy(joker);joker.assignEnemy(batman);//негодяй нападает первым:joker.start();batman.start();

Исход поединка определится тем, насколько часто один или другой поток получат управление.

Page 26: Java Core. Lecture# 3. Part# 3. Multithreading

Приоритет

Потоку можно установить относительный приоритет выполнения.

// Приоритет назначается в зависимости от рода задачи, выполняемой на немclass Runner extends Thread{

public Runner(){setPriority(Thread.MAX_PRIORITY);//Thread.MIN_PRIORITY//Thread.NORM_PRIORITY

start();}

}

Page 27: Java Core. Lecture# 3. Part# 3. Multithreading

Остановка потокаПоток можно принудительно остановить, если необходимость в нем отпала. Метод stop() использовать не рекомендуется:public class Combat extends Thread{

public Combat() { //при создании экземпляра запускаем поток this.start(); } public void run(){

while (true){/*бой продолжается*/ }}

}//На другом потоке:Thread combat = new Combat();combat.stop();

Page 28: Java Core. Lecture# 3. Part# 3. Multithreading

Остановка потока (cont.)Корректный способ остановки потока – с использованием выхода из цикла:public class FairCombat extends Thread {

volatile boolean win = false;public void run(){

while (true){// бой продолжается if(enemy.isEmpty()) {//до последнего противника win = true; return; } /* или до победы*/ if (win) {return;} }//while}

Page 29: Java Core. Lecture# 3. Part# 3. Multithreading

Вопросы?