Thread
Transcript of Thread
![Page 1: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/1.jpg)
Тема №11
Потоки (threads)
![Page 2: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/2.jpg)
Базові поняття Потоки (threads) - підтримка
багатопоточності на рівні самої мови.
В одній програмі можна запустити декілька потоків, які будуть працювати паралельно.
![Page 3: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/3.jpg)
Деякі застосування “Чутливі” графічні
застосування: в одному потоці виконується анімація та інші операції, а в іншому – кнопка для зупинки та інші елементи керування.
Сокети.
![Page 4: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/4.jpg)
Потоки: основи Кожний потік є екземпляром
класу Thread. Функціональність потоку
визначається методом run(). Потік завершується, коли завершується виконання коду цього методу (або виникає неперехоплене виключення).
Запуск потоку здійснюється методом start().
![Page 5: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/5.jpg)
Організація потоків: два способи
створення екземпляру класу, похідного від класу Thread;
реалізація інтерфейсу Runnable; досить типовим є використання анонімних класів.
![Page 6: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/6.jpg)
Приклад запуску потокуThread t = new Thread (new Runnable(){ public void run() { for (int i=0;i<1000;i++) { result+=Math.random()-0.5; } } }); t.start(); //Запуск потоку …
t.join(); //Без цього виведення може бути некоректним
System.out.println(“Result is "+result);
![Page 7: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/7.jpg)
Більш простий запуск (якщо достатньо анонімного потоку)
new Thread () {
@Override public void run() { for (int i=0;i<1000;i++) { result+=Math.random()-0.5; } System.out.println("Test indicator is
"+result); }
}.start();
![Page 8: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/8.jpg)
Клас, похідний від Thread Основна функціональність потоку
визначається в методі run(). Щоб запустити потік, потрібно викликати
метод start(), який викликає run(). Самого лише створення екземпляру
недостатньо для запуску потоку. Якщо просто викликати run() - потік не
запускається. Часто start() викликається в конструкторі, і
тоді потік запускається при створенні екземпляра.
![Page 9: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/9.jpg)
Реалізація інтерфейсу Runnable Наприклад, якщо клас уже є підкласом
деякого іншого класу. Функціональність визначається методом
run(). Типова схема запуску потоку: створюється
екземпляр класу Thread, конструктору якого передається вказівник на екземпляр нашого класу. Далі викликається start().
Знову-ж таки - часто в конструкторі, і тоді:Thread tr = new Thread(this);tr.start(); Досить типово – як анонімний клас.
![Page 10: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/10.jpg)
Приклад програми з кількома потоками Програма demopotok в каталозі
threads. Створюються три потоки; вони
реалізують той самий код, але роблять різні затримки, і тому працюють з різними швидкостями.
Кожний потік видає повідомлення про поточні значення змінних.
Кожний потік зупиняється після заданої кількості проходів.
![Page 11: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/11.jpg)
Коментарі: функціональність потокуpublic void run() {while (Passes<MaxPasses) {Passes++;TotalPasses++;System.out.println(Passes+"-th pass of thread number
"+Nomer+"; total passes - "+TotalPasses);try {sleep(Delay);}catch (InterruptedException e) {System.out.println("Something strange...");}}System.out.println ("Thread number "+Nomer+"
stopped");}
![Page 12: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/12.jpg)
Коментарі: конструктор
public potok(int Delay) {this.Delay=Delay;this.start();Number++;Nomer=Number;System.out.println("Thread number
"+Nomer+ " started");}
![Page 13: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/13.jpg)
Коментарі: початкова ініціалізаціяstatic int MaxPasses;static {System.out.println("Enter amounts of passes");try {BufferedReader br=new BufferedReader( new
InputStreamReader(System.in));MaxPasses = Integer.parseInt(br.readLine());}catch (Exception e) {System.exit(1);}}static int Number=0;static int TotalPasses=0;int Nomer=0;int Passes=0;int Delay;
![Page 14: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/14.jpg)
Коментарі: запуск потоків
potok tr1=new potok(1000);potok tr2=new potok(2000);potok tr3=new potok(5000);
![Page 15: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/15.jpg)
Використання змінних
Кожний потік отримує власні копії локальних змінних та полів екземпляра, але статичні поля спільно використовуються всіма потоками
![Page 16: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/16.jpg)
Пріоритети потоків Потоки можуть виконуватися з
різними пріоритетами. Константи класу Thread:
MIN_PRIORITY=1; NORM_PRIORITY=5; MAX_PRIORITY=10
Пріоритет може бути встановлений методом setPriority, хоча ручне управління пріоритетами не дуже рекомендується.
![Page 17: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/17.jpg)
Зупинка потоку
Є метод для явної зупинки, але ним користуватися не рекомендується.
Краще - цикл, в якому задати умову завершення потоку.
![Page 18: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/18.jpg)
Метод interrupt
Запит на переривання потоку. Встановлює в потоці статус
переривання. Не є примусовим
перериванням! Потік має сам вирішити, як обробляти цей запит!
![Page 19: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/19.jpg)
Приклад застосування interruptThread t = new MyThread(); t.start(); t.interrupt(); try { t.join(); } catch (InterruptedException ir) { System.out.println("InterruptedException
happened"); } }
![Page 20: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/20.jpg)
1-й варіант потоку: interrupt не працюєclass MyThread extends Thread { @Override public void run() { boolean b=true; while (b) { if (isInterrupted())
System.out.println("Request for interruption received");
System.out.println("I am still working!"); } System.out.println("Thread finished"); }}
![Page 21: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/21.jpg)
2-й варіант: потік зупиняєтьсяpublic void run() { boolean b=true; while (b) { if (isInterrupted()) { System.out.println("Request for interruption
received"); b=false; } System.out.println("I am still working!"); } System.out.println("Thread finished"); }
![Page 22: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/22.jpg)
Затримка потоку
Метод sleep(). Або викликається для
конкретного потоку, або Thread.sleep(мс);
![Page 23: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/23.jpg)
Метод join
Дозволяє дочекатися завершення іншого потоку. Наприклад, якщо потік tr1 робить виклик tr2.join(), то він призупиняється і чекає, поки tr2 не завершить роботу.
![Page 24: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/24.jpg)
Стани потоків New – створений, але не запущений. Runnable – запущений методом start. Dead – зупинений. Block – заблокований. Переходить до
заблокованого стану після методу sleep або wait, або якщо він чекає завершення операції введення-виведення, або якщо він чекає завершення синхронізованого методу.
![Page 25: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/25.jpg)
Метод yield
Передає управління іншому потоку з тим же пріоритетом.
![Page 26: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/26.jpg)
Синхронізація потоків
Проблема полягає в тому, що часто потрібно заборонити одночасний доступ різних потоків до певних об’єктів або одночасний виклик певних методів.
Основні методи синхронізації – за ресурсами та за подіями.
![Page 27: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/27.jpg)
Синхронізація за ресурсами
Ключове слово synchronized - у формі оператора та у формі модифікатора.
![Page 28: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/28.jpg)
Оператор synchronized
synchronized (expression) {statements}Вираз expression повертає об’єкт або
масив. Перед виконанням критичної секції (statements) цей об’єкт блокується, і ніякий інший потік не може мати до нього доступу, поки виконується критична секція.
![Page 29: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/29.jpg)
Приклад: сортування масиву
public static void sortIntArray( int[] a) {…synchronized (a) {Sorting}
}
![Page 30: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/30.jpg)
Synchronized як модифікатор
Якщо модифікатор synchronized використовується в описі методу - весь метод оголошується критичною секцією.
![Page 31: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/31.jpg)
Синхронізовані колекції
Collections.synchronizedList(new ArrayList());
Concurrent API.
![Page 32: Thread](https://reader036.fdocuments.in/reader036/viewer/2022062708/558c7998d8b42ada248b45ec/html5/thumbnails/32.jpg)
Координація потоків: ще один спосіб Методи wait() і notify() класу Object. Ідея -
потрібно, щоб потік призупинився і дочекався настання певної події. Якщо потік при роботі з об’єктом викликає метод wait(), він зупиняється і чекає, поки не буде викликаний метод notify() цього ж об’єкта.