Что такое findslide.org?

FindSlide.org - это сайт презентаций, докладов, шаблонов в формате PowerPoint.


Для правообладателей

Обратная связь

Email: Нажмите что бы посмотреть 

Яндекс.Метрика

Презентация на тему Java.SE.07 Multithreading

Содержание

2011 © EPAM Systems, RD Dep.СодержаниеПонятие многопоточностиРабота с потокамиСинхронизацияConcurrent
MULTITHREADINGIhar BlinouOracle Certified Java Instructorihar_blinou@epam.comJava.SE.072011 © EPAM Systems, RD Dep. 2011 © EPAM Systems, RD Dep.СодержаниеПонятие многопоточностиРабота с потокамиСинхронизацияConcurrent ПОНЯТИЕ МНОГОПОТОЧНОСТИ2011 © EPAM Systems, RD Dep. Понятие многопоточностиJava обеспечивает встроенную поддержку для многопоточного программирования. Многопоточная программа содержит две Понятие многопоточностиМногозадачные потоки требуют меньших накладных расходов по сравнению с многозадачными процессами. Понятие многопоточностиМногопоточность дает возможность писать очень эффективные программы, которые максимально используют CPU, Понятие многопоточностиИсполнительная система Java во многом зависит от потоков, и все библиотеки Понятие многопоточностиВыгода от многопоточности Java заключается в том, что устраняется механизм Понятие многопоточностиПотоки существуют в нескольких состояниях. Поток может быть в состоянии выполнения. Понятие многопоточности2011 © EPAM Systems, RD Dep. РАБОТА С ПОТОКАМИ2011 © EPAM Systems, RD Dep. Работа с потокамиМногопоточная система Java построена на классе Thread, его методах и Работа с потоками. Example 012011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public class Работа с потоками. Example 012011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public class Работа с потоками. Example 012011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public class Работа с потоками. Example 01Результат:2011 © EPAM Systems, RD Dep.TalkingWalkingWalkingTalkingWalkingTalkingTalkingWalkingWalkingTalkingWalkingTalkingWalkingTalkingWalkingTalking Работа с потокамиНекоторые методы класса Thread2011 © EPAM Systems, RD Dep. Работа с потокамиКогда Java-программа запускается, один поток начинает выполняться немедленно. Он обычно Работа с потокамиХотя главный поток создается автоматически после запуска программы, он может Работа с потоками. Example 022011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public class Работа с потоками. Example 02Результат:2011 © EPAM Systems, RD Dep.Текущий поток: Thread[main,5,main]После изменения имени: Thread[My Thread,5,main]54321 Работа с потокамиСуществуют два способа определения, закончился ли поток. Один из них Работа с потокамиВ то время как isAlive() полезен только иногда, чаще для Работа с потокамиСостояние потока возвращается методами int getState() и boolean isAlive() класса Работа с потоками. Example 032011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public class Работа с потоками. Example 032011 © EPAM Systems, RD Dep.class NewThread implements Работа с потоками. Example 03Результат:2011 © EPAM Systems, RD Dep.New thread: Thread[One,5,main]New Работа с потоками. Example 042011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public class Работа с потоками. Example 04Результат:2011 © EPAM Systems, RD Dep.Thread-0 RUNNABLEThread-0 TERMINATED Работа с потокамиВызов метода yield() для исполняемого потока должен приводить к приостановке Работа с потокамиПриоритеты потоковПланировщик потоков использует их приоритеты для принятия решений о Работа с потокамиВысокоприоритетный поток может также упреждать низкоприоритетный (т. е. перехватывать у Работа с потокамиДля безопасности потоки, которые совместно используют один и тот же Работа с потокамиДля установки приоритета потока используйте метод setPriority(), который является членом Работа с потокамиВы можете получить текущую установку приоритета, вызывая метод getPriority() класса Работа с потоками. Example 052011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public class Работа с потоками. Example 052011 © EPAM Systems, RD Dep.class Clicker implements Работа с потоками. Example 05Результат:2011 © EPAM Systems, RD Dep.Low-priority thread: 35443425High-priority thread: 36428949 Работа с потокамиГруппы потоковДля того, чтобы отдельный поток не мог начать останавливать Работа с потокамиГруппа потоков может содержать другие группы, что позволяет организовать все Работа с потокамиВсе потоки, объединенные группой, имеют одинаковый приоритет. Чтобы определить, к Работа с потоками. Example 062011 © EPAM Systems, RD Dep.package _java._se._07.startthread;class MyThread Работа с потоками. Example 062011 © EPAM Systems, RD Dep.	void suspendMe() {		suspended Работа с потоками. Example 062011 © EPAM Systems, RD Dep.public class ThreadCroupDemo Работа с потоками. Example 062011 © EPAM Systems, RD Dep.	  try Работа с потоками. Example 06Результат:2011 © EPAM Systems, RD Dep.New thread: Thread[One,5,Group Работа с потокамиПотоки-демоныПотоки-демоны работают в фоновом режиме вместе с программой, но не Работа с потоками. Example 072011 © EPAM Systems, RD Dep.package _java._se._07.startthread;class T Работа с потоками. Example 072011 © EPAM Systems, RD Dep.public class DaemonDemo Работа с потоками. Example 07Результат:2011 © EPAM Systems, RD Dep.старт потока-демонастарт обычного СИНХРОНИЗАЦИЯ2011 © EPAM Systems, RD Dep. СинхронизацияПравила, которые определяют, когда переключение контекста имеет место.Поток может добровольно отказаться от СинхронизацияПоскольку многопоточность обеспечивает асинхронное поведение ваших программ, должен существовать способ добиться синхронности, СинхронизацияДля этой цели Java эксплуатирует модель синхронизации процессов — монитор. Монитор — СинхронизацияБольшинство многопоточных систем создает мониторы как объекты, которые ваша программа должна явно СинхронизацияПосле того как вы разделите свою программу на отдельные потоки, нужно определить, СинхронизацияКогда несколько потоков нуждаются в доступе к разделяемому ресурсу, им необходим некоторый СинхронизацияТолько один поток может иметь собственный монитор в заданный момент. Когда поток СинхронизацияСинхронизация в Java проста потому, что каждый объект имеет свой собственный неявный Синхронизация. Example 082011 © EPAM Systems, RD Dep.package _java._se._07.synchro;public class SynchroMethodDemo { Синхронизация. Example 082011 © EPAM Systems, RD Dep.	 public static void main(String[] Синхронизация. Example 08Результат:2011 © EPAM Systems, RD Dep.threadA: objID=obj1 - entering doStuff()threadA: СинхронизацияХотя определения синхронизированных методов внутри классов — это простые и эффективные средства СинхронизацияВот общая форма оператора synchronized:synchronized(object) {// операторы для синхронизации}где object — ссылка Синхронизация. Example 092011 © EPAM Systems, RD Dep.package _java._se._07.synchro;public class SynchroBlockDemo {	public Синхронизация. Example 092011 © EPAM Systems, RD Dep.	public static void main(String[] args) Синхронизация. Example 09Результат:2011 © EPAM Systems, RD Dep.entering staticA()leaving staticA()in staticB() : inside sync block СинхронизацияВы можете достичь более тонкого уровня управления через связь между процессами. Многопоточность СинхронизацияНапример, рассмотрим классическую проблему организации очереди, где один поток производит некоторые данные, Синхронизацияwait ()  сообщает вызывающему потоку, что нужно уступить монитор и переходить Синхронизация. Example 102011 © EPAM Systems, RD Dep.package _java._se._07.synchro;class MyResource {	boolean ready Синхронизация. Example 102011 © EPAM Systems, RD Dep.class MyThread implements Runnable {	MyResource Синхронизация. Example 10Результат:2011 © EPAM Systems, RD Dep.MyThread is entering waitFor()...........MyThread resuming execution. СинхронизацияСпециальный тип ошибки, которую вам нужно избегать и которая специально относится к СинхронизацияВзаимоблокировка — трудная ошибка для отладки по двум причинам:Вообще говоря, она происходит СинхронизацияПриостановка выполнения потока иногда полезна. Например, отдельные потоки могут использоваться, чтобы отображать СинхронизацияДо Java 2 для приостановки и перезапуска выполнения потока программа использовала методы СинхронизацияВ Java 2 запрещено использовать методы suspend(), resume() или stop() для управления CONCURRENT2011 © EPAM Systems, RD Dep. СoncurrentВ Java версии 1.5 был добавлен новый пакет, содержащий много полезных возможностей, СoncurrentОграниченно потокобезопасные (thread safe) коллекции и вспомогательные классы управления потоками сосредоточены в Сoncurrentпараллельные аналоги существующих синхронизированых классов-коллекций ConcurrentHashMap (аналог Hashtable) и  CopyOnWriteArrayList (реализация Сoncurrentвысокопроизводительный класс Lock, поддерживающий ограниченные ожидания снятия блокировки, прерываемые попытки блокировки, очереди Сoncurrentклассы атомарных переменных (AtomicInteger, AtomicLong, AtomicReference), а также их высокопроизводительные аналоги SyncronizedInt СoncurrentExecutorsПакет java.util.concurrent содержит три Executor-интерфейса:ExecutorExecutorServiceScheduledExecutorServiceТакже библиотека java.util.concurrent содержит специальный класс, который называют Сoncurrent. Example 112011 © EPAM Systems, RD Dep.package executor;public class MyThread implements СoncurrentСначала создается объект класса ExecutorService. После чего вызывается метод execute, которому в СoncurrentВ примере объекту «ex» присваивается специальная реализация Executors.newCachedThreadPool(). Данная реализация применяется в СoncurrentExecutorServiceДанный интерфейс является расширением интерфейса Executor и добавляет следующие полезные возможности:Возможность остановить СoncurrentВозврат значений из задач. Интерфейс CallableОчень часто нам необходимо, чтобы поток после Сoncurrent. Example 122011 © EPAM Systems, RD Dep.package executorservice;import java.util.concurrent.Callable;public class MyThread СoncurrentТеперь рассмотрим способ получения полученного значения, используя исполнители. Для передачи объекта, созданного Сoncurrent. Example 13Результат:2011 © EPAM Systems, RD Dep.package executorservice;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import СoncurrentУправление потоками. ОжиданиеСуществует несколько методов управления потоками. Давайте рассмотрим метод переводящий поток Сoncurrent. Example 142011 © EPAM Systems, RD Dep.package timeunit;import java.util.concurrent.Callable;import java.util.concurrent.TimeUnit;public class СoncurrentМеханизм управления мьютексами LockLock является явным механизмом управления мьютексами. Он находиться в Сoncurrent. Example 152011 © EPAM Systems, RD Dep.package _java._se._07._concurrent;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class СoncurrentАтомарные операции. VolatileАтомарные операции- это операции, которые не могут быть прерваны планировщиком Сoncurrent. Example 16Атомарные классыПопробуем разрешить конфликт с помощью атомарных классов: AtomicInteger, Atomic Сoncurrent. Example 17Синхронизованные коллекции2011 © EPAM Systems, RD Dep.package _java._se._07._concurrent;import java.util.Random;import java.util.concurrent.PriorityBlockingQueue;class Сoncurrent. Example 172011 © EPAM Systems, RD Dep.class Manager implements Runnable {	private Сoncurrent. Example 172011 © EPAM Systems, RD Dep.class QueueTask{	private PriorityBlockingQueue queue = Сoncurrent. Example 172011 © EPAM Systems, RD Dep.public class PriorityBlockingQueueDemo {	public static Сoncurrent. Example 17Результат:2011 © EPAM Systems, RD Dep.Jonh get task number 2Jonh Сoncurrent. Example 17А вот возможный результат использования в этом примере PriorityQueue2011 © Java.SE.07MultiThreading2011 © EPAM Systems, RD Dep.Ihar Blinou, PhDOracle Certified Java InstructorIhar_blinou@epam.com
Слайды презентации

Слайд 2 2011 © EPAM Systems, RD Dep.
Содержание
Понятие многопоточности
Работа с

2011 © EPAM Systems, RD Dep.СодержаниеПонятие многопоточностиРабота с потокамиСинхронизацияConcurrent

потоками
Синхронизация
Concurrent


Слайд 3 ПОНЯТИЕ МНОГОПОТОЧНОСТИ
2011 © EPAM Systems, RD Dep.

ПОНЯТИЕ МНОГОПОТОЧНОСТИ2011 © EPAM Systems, RD Dep.

Слайд 4 Понятие многопоточности
Java обеспечивает встроенную поддержку для многопоточного программирования.

Понятие многопоточностиJava обеспечивает встроенную поддержку для многопоточного программирования. Многопоточная программа содержит



Многопоточная программа содержит две и более частей, которые могут

выполняться одновременно, конкурируя друг с другом.

Каждая часть такой программы называется потоком, а каждый поток определяет отдельный путь выполнения (в последовательности операторов программы).

Многопоточность — это специализированная форма многозадачности.

2011 © EPAM Systems, RD Dep.


Слайд 5 Понятие многопоточности
Многозадачные потоки требуют меньших накладных расходов по

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

сравнению с многозадачными процессами. Процессы — это тяжеловесные задачи,

которым требуются отдельные адресные пространства. Связи между процессами ограничены и стоят не дешево. Переключение контекста от одного процесса к другому также весьма дорогостоящая задача.

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

2011 © EPAM Systems, RD Dep.


Слайд 6 Понятие многопоточности
Многопоточность дает возможность писать очень эффективные программы,

Понятие многопоточностиМногопоточность дает возможность писать очень эффективные программы, которые максимально используют

которые максимально используют CPU, потому что время его простоя

можно свести к минимуму.

Это особенно важно для интерактивной сетевой среды, в которой работает Java, потому что время простоя является общим.

Скорость передачи данных по сети намного меньше, чем скорость, с которой компьютер может их обрабатывать.

В традиционной однопоточной среде ваша программа должна ждать окончания каждой своей задачи, прежде чем она сможет перейти к следующей (даже при том, что большую часть времени CPU простаивает).

Многопоточность позволяет получить доступ к этому времени простоя и лучше его использовать.

2011 © EPAM Systems, RD Dep.


Слайд 7 Понятие многопоточности
Исполнительная система Java во многом зависит от

Понятие многопоточностиИсполнительная система Java во многом зависит от потоков, и все

потоков, и все библиотеки классов разработаны с учетом многопоточности.



Java использует потоки для обеспечения асинхронности во всей среде.

Ценность многопоточной среды лучше понимается по контрасту с ее аналогом.
Однопоточные системы используют подход, называемый циклом событий с опросом (event loop with polling). В этой модели, единственный поток управления выполняется в бесконечном цикле, опрашивая единственную очередь событий, чтобы решить, что делать дальше. Как только этот механизм опроса возвращает сигнал готовности сетевого файла готов для чтения, цикл событий передает управление соответствующему обработчику событий. До возврата из этого обработчика в системе ничего больше случиться не может.

2011 © EPAM Systems, RD Dep.


Слайд 8 Понятие многопоточности
Выгода от многопоточности Java заключается в том,

Понятие многопоточностиВыгода от многопоточности Java заключается в том, что устраняется механизм

что устраняется механизм "главный цикл/опрос". Один поток может делать

паузу без остановки других частей программы. Например, время простоя, образующееся, когда поток читает данные из сети или ждет ввод пользователя, может использоваться в другом месте.


2011 © EPAM Systems, RD Dep.


Слайд 9 Понятие многопоточности
Потоки существуют в нескольких состояниях.

Поток может

Понятие многопоточностиПотоки существуют в нескольких состояниях. Поток может быть в состоянии

быть в состоянии выполнения.
Может находиться в состоянии готовности

к выполнению, как только он получит время CPU.
Выполняющийся поток может быть приостановлен, что временно притормаживает его действие.
Затем приостановленный поток может быть продолжен (возобновлен) с того места, где он был остановлен.
Поток может быть блокирован в ожидании ресурса. В любой момент выполнение потока может быть завершено, что немедленно останавливает его выполнение.

2011 © EPAM Systems, RD Dep.


Слайд 10 Понятие многопоточности
2011 © EPAM Systems, RD Dep.

Понятие многопоточности2011 © EPAM Systems, RD Dep.

Слайд 11 РАБОТА С ПОТОКАМИ
2011 © EPAM Systems, RD Dep.

РАБОТА С ПОТОКАМИ2011 © EPAM Systems, RD Dep.

Слайд 12 Работа с потоками
Многопоточная система Java построена на классе

Работа с потокамиМногопоточная система Java построена на классе Thread, его методах

Thread, его методах и связанном с ним интерфейсе Runnable.



Thread инкапсулирует поток выполнения. Так как вы не можете непосредственно обращаться к внутреннему состоянию потока выполнения, то будете иметь с ним дело через его полномочного представителя — экземпляр (объект) класса Thread, который его породил.

Чтобы создать новый поток, ваша программа должна будет или расширять класс Thread или реализовывать интерфейс Runnable.

2011 © EPAM Systems, RD Dep.


Слайд 13 Работа с потоками. Example 01
2011 © EPAM Systems,

Работа с потоками. Example 012011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public

RD Dep.
package _java._se._07.startthread;

public class Walk implements Runnable {
public void

run() {
for (int i = 0; i < 8; i++) {
System.out.println("Walking");
try {
Thread.sleep(400);
} catch (InterruptedException e) {
System.err.println(e);
}
}
}
}

Слайд 14 Работа с потоками. Example 01
2011 © EPAM Systems,

Работа с потоками. Example 012011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public

RD Dep.
package _java._se._07.startthread;

public class Talk extends Thread {
public void

run() {
for (int i = 0; i < 8; i++) {
System.out.println("Talking");
try {
// остановка на 400 миллисекунд
Thread.sleep(400);
} catch (InterruptedException e) {
System.err.print(e);
}
}
}
}

Слайд 15 Работа с потоками. Example 01
2011 © EPAM Systems,

Работа с потоками. Example 012011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public

RD Dep.
package _java._se._07.startthread;
public class DemoThead {
public static void main(String[]

args) {
// новые объекты потоков
Talk talk = new Talk();
Thread walk = new Thread(new Walk());
// запуск потоков
talk.start();
walk.start();
//Walk w = new Walk(); // просто объект, не поток
// w.run(); //выполнится метод, но поток не запустится!
}
}

Слайд 16 Работа с потоками. Example 01
Результат:
2011 © EPAM Systems,

Работа с потоками. Example 01Результат:2011 © EPAM Systems, RD Dep.TalkingWalkingWalkingTalkingWalkingTalkingTalkingWalkingWalkingTalkingWalkingTalkingWalkingTalkingWalkingTalking

RD Dep.
Talking
Walking
Walking
Talking
Walking
Talking
Talking
Walking
Walking
Talking
Walking
Talking
Walking
Talking
Walking
Talking


Слайд 17 Работа с потоками
Некоторые методы класса Thread


2011 © EPAM

Работа с потокамиНекоторые методы класса Thread2011 © EPAM Systems, RD Dep.

Systems, RD Dep.


Слайд 18 Работа с потоками
Когда Java-программа запускается, один поток начинает

Работа с потокамиКогда Java-программа запускается, один поток начинает выполняться немедленно. Он

выполняться немедленно.

Он обычно называется главным потоком.

Главный поток

важен по двум причинам:
Это поток, из которого будут порождены все другие "дочерние" потоки.
Это должен быть последний поток, в котором заканчивается выполнение. Когда главный поток останавливается, программа завершается.

2011 © EPAM Systems, RD Dep.


Слайд 19 Работа с потоками
Хотя главный поток создается автоматически после

Работа с потокамиХотя главный поток создается автоматически после запуска программы, он

запуска программы, он может управляться через Thread-объект. Для организации

управления нужно получить ссылку на него, вызывая метод Currentrhread (), который является public static членом класса Thread.

static Thread currentThread()

Этот метод возвращает ссылку на поток, в котором он вызывается. Как только вы получаете ссылку на главный поток, то можете управлять им точно так же, как любым другим потоком.

2011 © EPAM Systems, RD Dep.


Слайд 20 Работа с потоками. Example 02
2011 © EPAM Systems,

RD Dep.
package _java._se._07.startthread;
public class CurrentThreadDemo {
public static void main(String

args[]) {
Thread t = Thread.currentThread();
System.out.println("Текущий поток: " + t);
// изменить имя потока
t.setName("My Thread");
System.out.println("После изменения имени: " + t);
try {
for (int n = 5; n > 0; n--) {
System.out.println(n);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Главный поток завершен");
}
}
}

Слайд 21 Работа с потоками. Example 02
Результат:
2011 © EPAM Systems,

Работа с потоками. Example 02Результат:2011 © EPAM Systems, RD Dep.Текущий поток: Thread[main,5,main]После изменения имени: Thread[My Thread,5,main]54321

RD Dep.
Текущий поток: Thread[main,5,main]
После изменения имени: Thread[My Thread,5,main]
5
4
3
2
1


Слайд 22 Работа с потоками
Существуют два способа определения, закончился ли

Работа с потокамиСуществуют два способа определения, закончился ли поток. Один из

поток.

Один из них позволяет вызывать метод isAlive() на

потоке. Этот метод определен в Thread и его общая форма выглядит так:

final boolean isAlive()

Метод isAlive() возвращает true, если поток, на котором он вызывается — все еще выполняется. В противном случае возвращается false.

2011 © EPAM Systems, RD Dep.


Слайд 23 Работа с потоками
В то время как isAlive() полезен

Работа с потокамиВ то время как isAlive() полезен только иногда, чаще

только иногда, чаще для ожидания завершения потока вызывается метод

join() следующего формата:

final void join() throws InterruptedException

Этот метод ждет завершения потока, на котором он вызван. Его имя происходит из концепции перевода потока в состояние ожидания, пока указанный поток не присоединит его.

Дополнительные формы join() позволяют определять максимальное время ожидания завершения указанного потока.

2011 © EPAM Systems, RD Dep.


Слайд 24 Работа с потоками
Состояние потока возвращается методами int getState()

Работа с потокамиСостояние потока возвращается методами int getState() и boolean isAlive()

и boolean isAlive() класса Thread

2011 © EPAM Systems, RD

Dep.

Слайд 25 Работа с потоками. Example 03
2011 © EPAM Systems,

Работа с потоками. Example 032011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public

RD Dep.
package _java._se._07.startthread;
public class DemoJoin {
public static void main(String

args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
NewThread ob3 = new NewThread("Three");
System.out.println("Thread One is alive: " + ob1.t.isAlive());
System.out.println("Thread Two is alive: " + ob2.t.isAlive());
System.out.println("Thread Three is alive: " + ob3.t.isAlive());
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Thread One is alive: " + ob1.t.isAlive());
System.out.println("Thread Two is alive: " + ob2.t.isAlive());
System.out.println("Thread Three is alive: " + ob3.t.isAlive());
System.out.println("Main thread exiting.");
}
}

Слайд 26 Работа с потоками. Example 03
2011 © EPAM Systems,

RD Dep.
class NewThread implements Runnable {
String name; // name

of thread
Thread t;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
}

Слайд 27 Работа с потоками. Example 03
Результат:
2011 © EPAM Systems,

Работа с потоками. Example 03Результат:2011 © EPAM Systems, RD Dep.New thread:

RD Dep.
New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
One: 5
New thread: Thread[Three,5,main]
Two:

5
Thread One is alive: true
Thread Two is alive: true
Thread Three is alive: true
Waiting for threads to finish.
Three: 5
Two: 4
One: 4
Three: 4
One: 3
Three: 3
Two: 3
Three: 2
Two: 2
One: 2
Three: 1
One: 1
Two: 1
Three exiting.
One exiting.
Two exiting.
Thread One is alive: false
Thread Two is alive: false
Thread Three is alive: false
Main thread exiting.

Слайд 28 Работа с потоками. Example 04
2011 © EPAM Systems,

Работа с потоками. Example 042011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public

RD Dep.
package _java._se._07.startthread;
public class GetStateDemo implements Runnable{
public void run()

{
// Returns the state of this thread.
Thread.State state = Thread.currentThread().getState();
System.out.println(Thread.currentThread().getName() + " " + state);
}
public static void main(String args[]) {
Thread th1 = new Thread(new GetStateDemo());
th1.start();
try {
th1.sleep(1000);
} catch (Exception e) {
System.out.println(e);
}
// Returns the state of the thread.
Thread.State state = th1.getState();
System.out.println(th1.getName() + " " + state);
}
}

Слайд 29 Работа с потоками. Example 04
Результат:
2011 © EPAM Systems,

Работа с потоками. Example 04Результат:2011 © EPAM Systems, RD Dep.Thread-0 RUNNABLEThread-0 TERMINATED

RD Dep.
Thread-0 RUNNABLE
Thread-0 TERMINATED


Слайд 30 Работа с потоками
Вызов метода yield() для исполняемого потока

Работа с потокамиВызов метода yield() для исполняемого потока должен приводить к

должен приводить к приостановке потока на некоторый квант времени,

для того чтобы другие потоки могли выполнять свои действия. Однако если требуется надежная остановка потока, то следует использовать его крайне осторожно или вообще применить другой способ.

2011 © EPAM Systems, RD Dep.

class MyThread3 extends Thread {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("child thread");
Thread.yield();
}
}
}


Слайд 31 Работа с потоками
Приоритеты потоков

Планировщик потоков использует их приоритеты

Работа с потокамиПриоритеты потоковПланировщик потоков использует их приоритеты для принятия решений

для принятия решений о том, когда нужно разрешать выполнение

тому или иному потоку.

Теоретически высокоприоритетные потоки получают больше времени CPU, чем низкоприоритетные.

На практике, однако, количество времени CPU, которое поток получает, часто зависит от нескольких факторов помимо его приоритета. (Например, относительная доступность времени CPU может зависеть от того, как операционная система реализует многозадачный режим.)

2011 © EPAM Systems, RD Dep.


Слайд 32 Работа с потоками
Высокоприоритетный поток может также упреждать низкоприоритетный

Работа с потокамиВысокоприоритетный поток может также упреждать низкоприоритетный (т. е. перехватывать

(т. е. перехватывать у него управление процессором).

Скажем, когда

низкоприоритетный поток выполняется, а высокоприоритетный поток возобновляется (от ожидания на вводе/выводе, к примеру), высокоприоритетный поток будет упреждать низкоприоритетный.

Теоретически, потоки равного приоритета должны получить равный доступ к CPU.


2011 © EPAM Systems, RD Dep.


Слайд 33 Работа с потоками
Для безопасности потоки, которые совместно используют

Работа с потокамиДля безопасности потоки, которые совместно используют один и тот

один и тот же приоритет, должны время от времени

уступать друг другу управление.

Это гарантирует, что все потоки имеют шанс выполниться под неприоритетной операционной системой.

Практически, даже в неприоритетных средах, большинство потоков все еще получают шанс выполняться, потому что большинство из них неизбежно сталкивается с некоторыми блокирующими ситуациями, типа ожидания ввода/вывода.

Когда это случается, блокированный поток приостанавливается, а другие могут продолжаться.

2011 © EPAM Systems, RD Dep.


Слайд 34 Работа с потоками
Для установки приоритета потока используйте метод

Работа с потокамиДля установки приоритета потока используйте метод setPriority(), который является

setPriority(), который является членом класса Thread. Вот его общая

форма:

final void setPriority(int level)

где level определяет новую установку приоритета для вызывающего потока.

Значение параметра level должно быть в пределах диапазона min_priority и max_priority. В настоящее время эти значения равны 1 и 10, соответственно.
Чтобы вернуть потоку приоритет, заданный по умолчанию, определите norm_priority, который в настоящее время равен 5.
Эти приоритеты определены в Thread как final-переменные.

2011 © EPAM Systems, RD Dep.


Слайд 35 Работа с потоками
Вы можете получить текущую установку приоритета,

Работа с потокамиВы можете получить текущую установку приоритета, вызывая метод getPriority()

вызывая метод getPriority() класса Thread, чей формат имеет следующий

вид:

final int getPriority()

Реализации Java могут иметь радикально различное поведение, когда они переходят к планированию.

2011 © EPAM Systems, RD Dep.


Слайд 36 Работа с потоками. Example 05
2011 © EPAM Systems,

Работа с потоками. Example 052011 © EPAM Systems, RD Dep.package _java._se._07.startthread;public

RD Dep.
package _java._se._07.startthread;
public class PriorityDemo {
public static void main(String

args[]) {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
Clicker hi = new Clicker(Thread.NORM_PRIORITY + 2);
Clicker lo = new Clicker(Thread.NORM_PRIORITY - 2);
lo.start();
hi.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
lo.stop();
hi.stop();
// Wait for child threads to terminate.
try {
hi.t.join();
lo.t.join();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Low-priority thread: " + lo.click);
System.out.println("High-priority thread: " + hi.click);
}
}

Слайд 37 Работа с потоками. Example 05
2011 © EPAM Systems,

Работа с потоками. Example 052011 © EPAM Systems, RD Dep.class Clicker

RD Dep.
class Clicker implements Runnable {
int click = 0;
Thread

t;
private volatile boolean running = true;
public Clicker(int p) {
t = new Thread(this);
t.setPriority(p);
}
public void run() {
while (running) {
click++;
}
}
public void stop() {
running = false;
}
public void start() {
t.start();
}
}

Слайд 38 Работа с потоками. Example 05
Результат:
2011 © EPAM Systems,

Работа с потоками. Example 05Результат:2011 © EPAM Systems, RD Dep.Low-priority thread: 35443425High-priority thread: 36428949

RD Dep.
Low-priority thread: 35443425
High-priority thread: 36428949


Слайд 39 Работа с потоками
Группы потоков

Для того, чтобы отдельный поток

Работа с потокамиГруппы потоковДля того, чтобы отдельный поток не мог начать

не мог начать останавливать и прерывать все потоки подряд,

введено понятие группы.

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

Группу потоков представляет класс ThreadGroup.

Такая организация позволяет защитить потоки от нежелательного внешнего воздействия.

2011 © EPAM Systems, RD Dep.


Слайд 40 Работа с потоками
Группа потоков может содержать другие группы,

Работа с потокамиГруппа потоков может содержать другие группы, что позволяет организовать

что позволяет организовать все потоки и группы в иерархическое

дерево, в котором каждый объект ThreadGroup, за исключением корневого, имеет родителя.

Класс ThreadGroup обладает методами для изменения свойств всех входящих в него потоков, таких, как приоритет, daemon и т.д.

Метод list() позволяет получить список потоков.

2011 © EPAM Systems, RD Dep.


Слайд 41 Работа с потоками
Все потоки, объединенные группой, имеют одинаковый

Работа с потокамиВсе потоки, объединенные группой, имеют одинаковый приоритет. Чтобы определить,

приоритет.

Чтобы определить, к какой группе относится поток, следует

вызвать метод getThreadGroup().

Если поток до включения в группу имел приоритет выше приоритета группы потоков, то после включения значение его приритета станет равным приоритету группы.

Поток же со значением приоритета более низким, чем приоритет группы после включения в оную, значения своего приоритета не изменит.

2011 © EPAM Systems, RD Dep.


Слайд 42 Работа с потоками. Example 06
2011 © EPAM Systems,

RD Dep.
package _java._se._07.startthread;
class MyThread extends Thread {
boolean suspended;
MyThread(String threadname,

ThreadGroup tgOb) {
super(tgOb, threadname);
System.out.println("New thread: " + this);
suspended = false;
start(); // Start the thread
}
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println(getName() + ": " + i);
Thread.sleep(1000);
synchronized (this) {
while (suspended) {
wait();
}
}
}
} catch (Exception e) {
System.out.println("Exception in " + getName());
}
System.out.println(getName() + " exiting.");
}

Слайд 43 Работа с потоками. Example 06
2011 © EPAM Systems,

Работа с потоками. Example 062011 © EPAM Systems, RD Dep.	void suspendMe()

RD Dep.
void suspendMe() {
suspended = true;
}
synchronized void resumeMe() {
suspended

= false;
notify();
}
}

Слайд 44 Работа с потоками. Example 06
2011 © EPAM Systems,

Работа с потоками. Example 062011 © EPAM Systems, RD Dep.public class

RD Dep.
public class ThreadCroupDemo {

public static void main(String[] args){


ThreadGroup groupA = new ThreadGroup("Group A");
ThreadGroup groupB = new ThreadGroup("Group B");
MyThread ob1 = new MyThread("One", groupA);
MyThread ob2 = new MyThread("Two", groupA);
MyThread ob3 = new MyThread("Three", groupB);
MyThread ob4 = new MyThread("Four", groupB);
System.out.println("\nHere is output from list():");
groupA.list();
groupB.list();
System.out.println("Suspending Group A");
Thread tga[] = new Thread[groupA.activeCount()];
groupA.enumerate(tga); // get threads in group

for (int i = 0; i < tga.length; i++) {
((MyThread) tga[i]).suspendMe(); // suspend each thread
}



Слайд 45 Работа с потоками. Example 06
2011 © EPAM Systems,

Работа с потоками. Example 062011 © EPAM Systems, RD Dep.	 try

RD Dep.
try {
System.out.println("Waiting for

threads to finish.");
ob1.join();
ob2.join();
ob3.join();
ob4.join();
} catch (Exception e) {
System.out.println("Exception in Main thread");
}
System.out.println("Main thread exiting.");
}
}

Слайд 46 Работа с потоками. Example 06
Результат:
2011 © EPAM Systems,

Работа с потоками. Example 06Результат:2011 © EPAM Systems, RD Dep.New thread:

RD Dep.
New thread: Thread[One,5,Group A]
New thread: Thread[Two,5,Group A]
One: 5
New

thread: Thread[Three,5,Group B]
Two: 5
New thread: Thread[Four,5,Group B]
Three: 5
Here is output from list():
java.lang.ThreadGroup[name=Group A,maxpri=10]
Thread[One,5,Group A]
Thread[Two,5,Group A]
Four: 5
java.lang.ThreadGroup[name=Group B,maxpri=10]
Thread[Three,5,Group B]
Thread[Four,5,Group B]
Suspending Group A
Three: 4
Four: 4
Resuming Group A
Two: 4

Waiting for threads to finish.
One: 4
Three: 3
One: 3
Two: 3
Four: 3
Three: 2
Two: 2
One: 2
Four: 2
Three: 1
One: 1
Two: 1
Four: 1
Three exiting.
Two exiting.
One exiting.
Four exiting.
Main thread exiting.


Слайд 47 Работа с потоками
Потоки-демоны

Потоки-демоны работают в фоновом режиме вместе

Работа с потокамиПотоки-демоныПотоки-демоны работают в фоновом режиме вместе с программой, но

с программой, но не являются неотъемлемой частью программы.

Если

какой-либо процесс может выполняться на фоне работы основных потоков выполнения и его деятельность заключается в обслуживании основных потоков приложения, то такой процесс может быть запущен как поток-демон.

С помощью метода setDaemon(boolean value), вызванного вновь созданным потоком до его запуска, можно определить поток-демон. Метод boolean isDaemon() позволяет определить, является ли указанный поток демоном или нет.

2011 © EPAM Systems, RD Dep.


Слайд 48 Работа с потоками. Example 07
2011 © EPAM Systems,

Работа с потоками. Example 072011 © EPAM Systems, RD Dep.package _java._se._07.startthread;class

RD Dep.
package _java._se._07.startthread;
class T extends Thread {
public void run()

{
try {
if (isDaemon()) {
System.out.println("старт потока-демона");
sleep(1000); // заменить параметр на 1
} else {
System.out.println("старт обычного потока");
sleep(100);
}
} catch (InterruptedException e) {
System.err.print("Error" + e);
} finally {
if (!isDaemon()){
System.out.println("завершение обычного потока");
}
else
System.out.println("завершение потока-демона");
}
}
}

Слайд 49 Работа с потоками. Example 07
2011 © EPAM Systems,

Работа с потоками. Example 072011 © EPAM Systems, RD Dep.public class

RD Dep.
public class DaemonDemo {
public static void main(String[] args)

{
T usual = new T();
T daemon = new T();
daemon.setDaemon(true);
daemon.start();
usual.start();
System.out.println("последний оператор main");
}
}

Слайд 50 Работа с потоками. Example 07
Результат:
2011 © EPAM Systems,

Работа с потоками. Example 07Результат:2011 © EPAM Systems, RD Dep.старт потока-демонастарт

RD Dep.
старт потока-демона
старт обычного потока
последний оператор main
завершение обычного потока


Слайд 51 СИНХРОНИЗАЦИЯ
2011 © EPAM Systems, RD Dep.

СИНХРОНИЗАЦИЯ2011 © EPAM Systems, RD Dep.

Слайд 52 Синхронизация
Правила, которые определяют, когда переключение контекста имеет место.
Поток

СинхронизацияПравила, которые определяют, когда переключение контекста имеет место.Поток может добровольно отказаться

может добровольно отказаться от управления. Это делается явно, переходом

в режим ожидания или блокированием на ожидающем вводе/выводе. В этом сценарии просматриваются все потоки, и CPU передается самому высокоприоритетному потоку, который готов к выполнению.
Поток может быть приостановлен более приоритетным потоком. В этом случае занимающий процессор низкоприоритетный поток временно останавливается (независимо от того, что он делает) потоком с более высоким приоритетом. Данный механизм называется упреждающей многозадачностью (preemptive multitasking).

2011 © EPAM Systems, RD Dep.


Слайд 53 Синхронизация
Поскольку многопоточность обеспечивает асинхронное поведение ваших программ, должен

СинхронизацияПоскольку многопоточность обеспечивает асинхронное поведение ваших программ, должен существовать способ добиться

существовать способ добиться синхронности, когда в этом возникает необходимость.



Например, если вы хотите, чтобы два потока взаимодействовали и совместно использовали сложную структуру данных типа связного списка, нужно каким-то образом гарантировать отсутствие между ними конфликтов.

Вы должны удержать один поток от записи данных, пока другой поток находится в процессе их чтения.

2011 © EPAM Systems, RD Dep.


Слайд 54 Синхронизация
Для этой цели Java эксплуатирует модель синхронизации процессов

СинхронизацияДля этой цели Java эксплуатирует модель синхронизации процессов — монитор. Монитор

— монитор.

Монитор — это механизм управления связью между

процессами. Вы можете представлять монитор, как очень маленький блок, который содержит только один поток. Как только поток входит в монитор, все другие потоки должны ждать, пока данный не выйдет из монитора. Таким образом, монитор можно использовать для защиты совместно используемого (разделяемого) ресурса от управления несколькими потоками одновременно.

2011 © EPAM Systems, RD Dep.


Слайд 55 Синхронизация
Большинство многопоточных систем создает мониторы как объекты, которые

СинхронизацияБольшинство многопоточных систем создает мониторы как объекты, которые ваша программа должна

ваша программа должна явно получить и использовать.

В Java-системе

нет класса с именем Monitor. Вместо этого, каждый объект имеет свой собственный неявный монитор, который вводится автоматически при вызове одного из методов объекта.

Как только поток оказывается внутри синхронизированного метода, никакой другой поток не может вызывать иной синхронизированный метод того же объекта.

2011 © EPAM Systems, RD Dep.


Слайд 56 Синхронизация
После того как вы разделите свою программу на

СинхронизацияПосле того как вы разделите свою программу на отдельные потоки, нужно

отдельные потоки, нужно определить, как они будут взаимодействовать друг

с другом.

Java обеспечивает ясный, дешевый путь для взаимного общения двух (или нескольких) потоков через вызовы предопределенных методов, которыми обладают все объекты.

Система передачи сообщений Java позволяет потоку войти в синхронизированный метод на объекте и затем ждать там, пока некоторый другой поток явно не уведомит его о выходе.

2011 © EPAM Systems, RD Dep.


Слайд 57 Синхронизация
Когда несколько потоков нуждаются в доступе к разделяемому

СинхронизацияКогда несколько потоков нуждаются в доступе к разделяемому ресурсу, им необходим

ресурсу, им необходим некоторый способ гарантии того, что ресурс

будет использоваться одновременно только одним потоком.

Процесс, с помощью которого это достигается, называется синхронизацией.

Ключом к синхронизации является концепция монитора (также называемая семафором).

Монитор — это объект, который используется для взаимоисключающей блокировки (mutually exclusive lock), или mutex.

2011 © EPAM Systems, RD Dep.


Слайд 58 Синхронизация
Только один поток может иметь собственный монитор в

СинхронизацияТолько один поток может иметь собственный монитор в заданный момент. Когда

заданный момент.

Когда поток получает блокировку, говорят, что он

вошел в монитор. Все другие потоки пытающиеся вводить блокированный монитор, будут приостановлены, пока первый не вышел из монитора.

Говорят, что другие потоки ожидают монитор.

При желании поток, владеющий монитором, может повторно вводить тот же самый монитор.

Синхронизировать код можно двумя способами. Оба используют ключевое слово synchronized.

2011 © EPAM Systems, RD Dep.


Слайд 59 Синхронизация
Синхронизация в Java проста потому, что каждый объект

СинхронизацияСинхронизация в Java проста потому, что каждый объект имеет свой собственный

имеет свой собственный неявный связанный с ним монитор.

Чтобы

ввести монитор объекта, просто вызывают метод, который был модифицирован ключевым словом synchronized.

Пока поток находится внутри синхронизированного метода, все другие потоки, пытающиеся вызвать его (или любой другой синхронизированный метод) на том же самом экземпляре, должны ждать.

Чтобы выйти из монитора и оставить управление объектом следующему ожидающему потоку, владелец монитора просто возвращается из синхронизированного метода.

2011 © EPAM Systems, RD Dep.


Слайд 60 Синхронизация. Example 08
2011 © EPAM Systems, RD Dep.
package

Синхронизация. Example 082011 © EPAM Systems, RD Dep.package _java._se._07.synchro;public class SynchroMethodDemo

_java._se._07.synchro;
public class SynchroMethodDemo {
private String objID;
public SynchroMethodDemo(String

objID) {
this.objID = objID;
}
public synchronized void doStuff(int val) {
print("entering doStuff()");
int num = val * 2 + objID.length();
print("local variable num=" + num);
try {
Thread.sleep(2000);
} catch (InterruptedException x) {
}
print("leaving doStuff()");
}
public void print(String msg) {
threadPrint("objID=" + objID + " - " + msg);
}
public static void threadPrint(String msg) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + ": " + msg);
}


Слайд 61 Синхронизация. Example 08
2011 © EPAM Systems, RD Dep.

Синхронизация. Example 082011 © EPAM Systems, RD Dep.	 public static void

public static void main(String[] args) {
final SynchroMethodDemo

ooim = new SynchroMethodDemo("obj1");
Runnable runA = new Runnable() {
public void run() {
ooim.doStuff(3);
}
};
Thread threadA = new Thread(runA, "threadA");
threadA.start();
try {
Thread.sleep(200);
} catch (InterruptedException x) {
}
Runnable runB = new Runnable() {
public void run() {
ooim.doStuff(7);
}
};
Thread threadB = new Thread(runB, "threadB");
threadB.start();
}
}

Слайд 62 Синхронизация. Example 08
Результат:
2011 © EPAM Systems, RD Dep.
threadA:

Синхронизация. Example 08Результат:2011 © EPAM Systems, RD Dep.threadA: objID=obj1 - entering

objID=obj1 - entering doStuff()
threadA: objID=obj1 - local variable num=10
threadA:

objID=obj1 - leaving doStuff()
threadB: objID=obj1 - entering doStuff()
threadB: objID=obj1 - local variable num=18
threadB: objID=obj1 - leaving doStuff()

Слайд 63 Синхронизация
Хотя определения синхронизированных методов внутри классов — это

СинхронизацияХотя определения синхронизированных методов внутри классов — это простые и эффективные

простые и эффективные средства достижения синхронизации, они не будут

работать во всех случаях.

Например, вы хотите синхронизировать доступ к объектам класса, который не был разработан для многопоточного доступа. То есть класс не использует синхронизированные методы.

Кроме того, этот класс был создан не вами, а третьим лицом, и вы не имеете доступа к исходному коду.

Таким образом, вы не можете добавлять спецификатор synchronized к соответствующим методам в классе.

Решение данной проблемы весьма просто. Нужно поместить вызовы методов, определенных этим классом внутрь синхронизированного блока.

2011 © EPAM Systems, RD Dep.


Слайд 64 Синхронизация
Вот общая форма оператора synchronized:

synchronized(object) {
// операторы для

СинхронизацияВот общая форма оператора synchronized:synchronized(object) {// операторы для синхронизации}где object —

синхронизации
}

где object — ссылка на объект, который нужно синхронизировать.



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

Блок гарантирует, что вызов метода, который является членом объекта object, происходит только после того, как текущий поток успешно ввел монитор объекта.

2011 © EPAM Systems, RD Dep.


Слайд 65 Синхронизация. Example 09
2011 © EPAM Systems, RD Dep.
package

Синхронизация. Example 092011 © EPAM Systems, RD Dep.package _java._se._07.synchro;public class SynchroBlockDemo

_java._se._07.synchro;
public class SynchroBlockDemo {
public static synchronized void staticA() {
System.out.println("entering

staticA()");
try {
Thread.sleep(5000);
} catch (InterruptedException x) {
}
System.out.println("leaving staticA()");
}
public static void staticB() {
synchronized (SynchroBlockDemo.class) {
System.out.println("in staticB() : inside sync block");
try {
Thread.sleep(2000);
} catch (InterruptedException x) {
}
}
}


Слайд 66 Синхронизация. Example 09
2011 © EPAM Systems, RD Dep.
public

Синхронизация. Example 092011 © EPAM Systems, RD Dep.	public static void main(String[]

static void main(String[] args) {
Runnable runA = new Runnable()

{
public void run() {
SynchroBlockDemo.staticA();
}
};
Thread threadA = new Thread(runA, "A");
threadA.start();
try {
Thread.sleep(200);
} catch (InterruptedException x) {
}
Runnable runB = new Runnable() {
public void run() {
SynchroBlockDemo.staticB();
}
};
Thread threadB = new Thread(runB, "B");
threadB.start();
}
}

Слайд 67 Синхронизация. Example 09
Результат:
2011 © EPAM Systems, RD Dep.
entering

Синхронизация. Example 09Результат:2011 © EPAM Systems, RD Dep.entering staticA()leaving staticA()in staticB() : inside sync block

staticA()
leaving staticA()
in staticB() : inside sync block


Слайд 68 Синхронизация
Вы можете достичь более тонкого уровня управления через

СинхронизацияВы можете достичь более тонкого уровня управления через связь между процессами.

связь между процессами.

Многопоточность заменяет программирование цикла событий, делением

задач на дискретные и логические модули.

Потоки также обеспечивают и второе преимущество — они отменяют опрос. Опрос обычно реализуется циклом, который используется для повторяющейся проверки некоторого условия.

Как только условие становится истинным, предпринимается соответствующее действие. На этом теряется время CPU.

2011 © EPAM Systems, RD Dep.


Слайд 69 Синхронизация
Например, рассмотрим классическую проблему организации очереди, где один

СинхронизацияНапример, рассмотрим классическую проблему организации очереди, где один поток производит некоторые

поток производит некоторые данные, а другой — их потребляет.



Предположим, что, прежде чем генерировать большее количество данных, производитель должен ждать, пока потребитель не закончит свою работу.

В системе же опроса, потребитель тратил бы впустую много циклов CPU на ожидание конца работы производителя. Как только производитель закончил свою работу, он вынужден начать опрос, затрачивая много циклов CPU на ожидание конца работы потребителя. Ясно, что такая ситуация нежелательна.

Чтобы устранить опросы, Java содержит изящный механизм межпроцессовой связи через методы wait(), notify() и notifyAll(). Они реализованы как final-методы в классе object, поэтому доступны всем классам

2011 © EPAM Systems, RD Dep.


Слайд 70 Синхронизация
wait () сообщает вызывающему потоку, что нужно

Синхронизацияwait () сообщает вызывающему потоку, что нужно уступить монитор и переходить

уступить монитор и переходить в режим ожидания ("спячки"), пока

некоторый другой поток не введет тот же монитор и не вызовет notify ();
notify () "пробуждает" первый поток (который вызвал wait ()) на том же самом объекте;
notifyAll() пробуждает все потоки, которые вызывали wait () на том же самом объекте. Первым будет выполняться самый высокоприоритетный поток.


Эти методы объявляются в классе Object в следующей форме:

final void wait() throws InterruptedException
final void notify()
final void notifyAll()

2011 © EPAM Systems, RD Dep.


Слайд 71 Синхронизация. Example 10
2011 © EPAM Systems, RD Dep.
package

Синхронизация. Example 102011 © EPAM Systems, RD Dep.package _java._se._07.synchro;class MyResource {	boolean

_java._se._07.synchro;
class MyResource {
boolean ready = false;
synchronized void waitFor() throws

Exception {
System.out.println(Thread.currentThread().getName()
+ " is entering waitFor().");
while (!ready)
wait();
System.out.println(Thread.currentThread().getName()
+ " resuming execution.");
}
synchronized void start() {
ready = true;
notify();
}
}

Слайд 72 Синхронизация. Example 10
2011 © EPAM Systems, RD Dep.
class

Синхронизация. Example 102011 © EPAM Systems, RD Dep.class MyThread implements Runnable

MyThread implements Runnable {
MyResource myResource;
MyThread(String name, MyResource so) {
myResource

= so;
new Thread(this, name).start();
}
public void run() {
try {
myResource.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class WaitNotifyDemo {
public static void main(String args[]) throws Exception {
MyResource sObj = new MyResource();
new MyThread("MyThread", sObj);
for (int i = 0; i < 10; i++) {
Thread.sleep(50);
System.out.print(".");
}
sObj.start();
}
}

Слайд 73 Синхронизация. Example 10
Результат:
2011 © EPAM Systems, RD Dep.
MyThread

Синхронизация. Example 10Результат:2011 © EPAM Systems, RD Dep.MyThread is entering waitFor()...........MyThread resuming execution.

is entering waitFor().
..........MyThread resuming execution.


Слайд 74 Синхронизация
Специальный тип ошибки, которую вам нужно избегать и

СинхронизацияСпециальный тип ошибки, которую вам нужно избегать и которая специально относится

которая специально относится к многозадачности, это — (взаимная) блокировка.



Она происходит, когда два потока имеют циклическую зависимость от пары синхронизированных объектов.

Например, предположим, что один поток вводит монитор в объект х, а другой поток вводит монитор в объект у. Если поток в х пробует вызвать любой синхронизированный метод объекта у, это приведет к блокировке, как и ожидается.

Однако если поток в у, в свою очередь, пробует вызвать любой синхронизированный метод объекта х, то он будет всегда ждать, т. к. для получения доступа к х, он был бы должен снять свою собственную блокировку с у, чтобы первый поток мог завершиться.

2011 © EPAM Systems, RD Dep.


Слайд 75 Синхронизация
Взаимоблокировка — трудная ошибка для отладки по двум

СинхронизацияВзаимоблокировка — трудная ошибка для отладки по двум причинам:Вообще говоря, она

причинам:

Вообще говоря, она происходит очень редко, когда интервалы временного

квантования двух потоков находятся в определенном соотношении.
Она может включать больше двух потоков и синхронизированных объектов.

2011 © EPAM Systems, RD Dep.


Слайд 76 Синхронизация
Приостановка выполнения потока иногда полезна.

Например, отдельные потоки

СинхронизацияПриостановка выполнения потока иногда полезна. Например, отдельные потоки могут использоваться, чтобы

могут использоваться, чтобы отображать время дня. Если пользователь не

хочет видеть отображения часов, то их поток может быть приостановлен. В любом случае приостановка потока — простое дело. После приостановки перезапуск потока также не сложен.

Механизмы приостановки, остановки и возобновления потоков различны для Java 2 и более ранних версий Java.

2011 © EPAM Systems, RD Dep.


Слайд 77 Синхронизация
До Java 2 для приостановки и перезапуска выполнения

СинхронизацияДо Java 2 для приостановки и перезапуска выполнения потока программа использовала

потока программа использовала методы suspend () и resume (),

которые определены в классе Thread. Они имеют такую форму:

final void suspend()
final void resume()

Класс Thread также определяет метод с именем stop(), который останавливает поток. Его сигнатура имеет следующий вид:

void stop()

Если поток был остановлен, то его нельзя перезапускать с помощью метода resume().

2011 © EPAM Systems, RD Dep.


Слайд 78 Синхронизация
В Java 2 запрещено использовать методы suspend(), resume()

СинхронизацияВ Java 2 запрещено использовать методы suspend(), resume() или stop() для

или stop() для управления потоком.

Поток должен быть спроектирован так,

чтобы метод run() периодически проверял, должен ли этот поток приостанавливать, возобновлять или останавливать свое собственное выполнение.

Это, как правило, выполняется применением флажковой переменной, которая указывает состояние выполнения потока.

Пока флажок установлен на "выполнение", метод run() должен продолжать позволять потоку выполняться.

Если эта переменная установлена на "приостановить", поток должен сделать паузу. Если она установлена на "стоп", поток должен завершиться.

2011 © EPAM Systems, RD Dep.


Слайд 79 CONCURRENT
2011 © EPAM Systems, RD Dep.

CONCURRENT2011 © EPAM Systems, RD Dep.

Слайд 80 Сoncurrent
В Java версии 1.5 был добавлен новый пакет,

СoncurrentВ Java версии 1.5 был добавлен новый пакет, содержащий много полезных

содержащий много полезных возможностей, касающихся синхронизации и параллелизма: java.util.concurrent.



В версии 1.5 языка добавлены пакеты классов java.util.concurrent.locks, java.util.concurrent.atomic, java.util.concurrent, возможности которых обеспечивают более высокую производительность, масштабируемость, построение потокобезопасных блоков параллельных (concurrent) классов, вызов утилит синхронизации, использование семафоров, ключей и atomic-переменных.

2011 © EPAM Systems, RD Dep.


Слайд 81 Сoncurrent
Ограниченно потокобезопасные (thread safe) коллекции и вспомогательные классы

СoncurrentОграниченно потокобезопасные (thread safe) коллекции и вспомогательные классы управления потоками сосредоточены

управления потоками сосредоточены в пакете java.util.concurrent. Среди них можно

отметить:

параллельные классы очередей ArrayBlockingQueue (FIFO очередь с фиксированой длиной), PriorityBlockingQueue (очередь с приоритетом) и ConcurrentLinkedQueue (FIFO очередь с нефиксированой длиной);

2011 © EPAM Systems, RD Dep.


Слайд 82 Сoncurrent
параллельные аналоги существующих синхронизированых классов-коллекций ConcurrentHashMap (аналог Hashtable)

Сoncurrentпараллельные аналоги существующих синхронизированых классов-коллекций ConcurrentHashMap (аналог Hashtable) и CopyOnWriteArrayList (реализация

и CopyOnWriteArrayList (реализация List, оптимизированная для случая, когда количество

итераций во много раз превосходит количество вставок и удалений);

механизм управления заданиями, основанный на возможностях класса Executor, включающий пул потоков и службу их планирования;

2011 © EPAM Systems, RD Dep.


Слайд 83 Сoncurrent
высокопроизводительный класс Lock, поддерживающий ограниченные ожидания снятия блокировки,

Сoncurrentвысокопроизводительный класс Lock, поддерживающий ограниченные ожидания снятия блокировки, прерываемые попытки блокировки,

прерываемые попытки блокировки, очереди блокировки и установку ожидания снятия

нескольких блокиро­вок посредством класса Condition;

классы синхронизации общего назначения, такие как Semaphore, CountDownLatch (позволяет потоку ожидать завершения нескольких операций в других потоках), CyclicBarrier (позволяет нескольким потокам ожидать момента, когда они все достигнут какой-либо точки) и Exchanger (позволяет потокам синхронизироваться и обмениваться информацией);

2011 © EPAM Systems, RD Dep.


Слайд 84 Сoncurrent
классы атомарных переменных (AtomicInteger, AtomicLong, AtomicReference), а также

Сoncurrentклассы атомарных переменных (AtomicInteger, AtomicLong, AtomicReference), а также их высокопроизводительные аналоги

их высокопроизводительные аналоги SyncronizedInt и др.;

обработка неотловленных прерываний: класс

Thread теперь поддерживает установку обработчика на неотловленные прерывания (подобное ранее было доступно только в ThreadGroup).

2011 © EPAM Systems, RD Dep.


Слайд 85 Сoncurrent
Executors

Пакет java.util.concurrent содержит три Executor-интерфейса:

Executor
ExecutorService
ScheduledExecutorService

Также библиотека java.util.concurrent содержит

СoncurrentExecutorsПакет java.util.concurrent содержит три Executor-интерфейса:ExecutorExecutorServiceScheduledExecutorServiceТакже библиотека java.util.concurrent содержит специальный класс, который

специальный класс, который называют Executors. Объекты данного класса помогаю

работать с потока не на прямую, а использовать исполнители. Данное решение бывает очень полезно когда вам необходимо запустить множество потоков, выполняющих одинаковые задачи.

2011 © EPAM Systems, RD Dep.


Слайд 86 Сoncurrent. Example 11
2011 © EPAM Systems, RD Dep.
package

Сoncurrent. Example 112011 © EPAM Systems, RD Dep.package executor;public class MyThread

executor;
public class MyThread implements Runnable {
public int count =

0;
public void run() {
for (int i = 0; i < 1000000; i++) {
count++;
}
System.out.println(count);
}
}

package executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Solution {
public static void main(String[] args) {
ExecutorService ex = Executors.newCachedThreadPool();
ex.execute(new MyThread());
ex.execute(new MyThread());
}
}


Слайд 87 Сoncurrent
Сначала создается объект класса ExecutorService. После чего вызывается

СoncurrentСначала создается объект класса ExecutorService. После чего вызывается метод execute, которому

метод execute, которому в качестве параметра необходимо передать объект,

созданного нами класса, который мы хотим передать исполнителю.

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

Исполнитель позволяет нам экономить время на создание отдельных потоков и на их запуск.

Результат:

2011 © EPAM Systems, RD Dep.


Слайд 88 Сoncurrent
В примере объекту «ex» присваивается специальная реализация Executors.newCachedThreadPool().

СoncurrentВ примере объекту «ex» присваивается специальная реализация Executors.newCachedThreadPool(). Данная реализация применяется

Данная реализация применяется в тех случаях, когда вы заранее

неизвестно, какое количество потоков будет передаваться исполнителю.

Если же количество потоков заранее известно необходимо использовать реализацию newFixedThreadPool(int) в качестве параметра ей нужно передать число потоков, которое мы будем использовать, в нашем случае 2. Это дает большой выигрыш в быстродействии, так как все потоки создаются сразу.

Если же необходимо передавать исполнителю только один объект класса, то для таких целей можно использовать реализацию newSingleThreadExecutor(). Если при использовании данной реализации исполнителю передается несколько потоков, то они попадут в очередь, и каждый из них будет запускаться только после завершения работы предыдущего.

2011 © EPAM Systems, RD Dep.


Слайд 89 Сoncurrent
ExecutorService

Данный интерфейс является расширением интерфейса Executor и добавляет

СoncurrentExecutorServiceДанный интерфейс является расширением интерфейса Executor и добавляет следующие полезные возможности:Возможность

следующие полезные возможности:

Возможность остановить выполняемый процесс
Возможность выполнения не только

Runnable объектов, но и java.util.concurrent.Callable. Основное их отличие от Runnable объектов – возможность возвращать значение потоку, из которого делался вызов.
Возможность возвращать вызывавшему потоку объект java.util.concurrent.Future, который содержит среди прочего и возвращаемое значение.

2011 © EPAM Systems, RD Dep.


Слайд 90 Сoncurrent
Возврат значений из задач. Интерфейс Callable

Очень часто нам

СoncurrentВозврат значений из задач. Интерфейс CallableОчень часто нам необходимо, чтобы поток

необходимо, чтобы поток после выполнения своей работы возвращал нам

некоторое значение, в таких ситуациях нам необходимо использовать интерфейс Callable при создании класса. Он очень похож на Runnable, но имеет несколько отличий.

В первую очередь после объявления данного интерфейса необходимо указать тип параметра, который должен вернуть поток.
Вместо метода run() необходимо использовать метод call().

2011 © EPAM Systems, RD Dep.


Слайд 91 Сoncurrent. Example 12
2011 © EPAM Systems, RD Dep.
package

Сoncurrent. Example 122011 © EPAM Systems, RD Dep.package executorservice;import java.util.concurrent.Callable;public class

executorservice;
import java.util.concurrent.Callable;
public class MyThread implements Callable {
public int count

= 0;
public Integer call() {
for (int i = 0; i < 1000000; i++) {
count++;
}

try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return count;
}
}

В данном примере метод call() вернет нам число после завершения операции.


Слайд 92 Сoncurrent
Теперь рассмотрим способ получения полученного значения, используя исполнители.

СoncurrentТеперь рассмотрим способ получения полученного значения, используя исполнители. Для передачи объекта,



Для передачи объекта, созданного нами класса исполнителя, используется метод

«submit».

При вызове данного метода создается объект типа «Future» параметризованный по типу результата возвращаемого Callable. В нашем случае «Future». В свою очередь из этого объекта мы уже можем получить нужный нам результат, используя метод get(). Данный метод всегда необходимо оборачивать в блок try-catch , так как поток еще может не закончить свою работу, а метод get() уже будет вызван.

Для проверки завершенности потока используется метод isDone(), он возвращает логическое значение.

2011 © EPAM Systems, RD Dep.


Слайд 93 Сoncurrent. Example 13
Результат:
2011 © EPAM Systems, RD Dep.
package

Сoncurrent. Example 13Результат:2011 © EPAM Systems, RD Dep.package executorservice;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import

executorservice;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Solution {
public

static void main(String[] args) {
ExecutorService ex = Executors.newCachedThreadPool();
Future s = ex.submit(new MyThread());
Future s1 = ex.submit(new MyThread());
try {
System.out.println("а я уже здесь");
System.out.println(s.get());
System.out.println(s1.get());
} catch (InterruptedException e) { e.printStackTrace();
} catch (ExecutionException e) {e.printStackTrace(); }
}
}

Слайд 94 Сoncurrent
Управление потоками. Ожидание

Существует несколько методов управления потоками. Давайте

СoncurrentУправление потоками. ОжиданиеСуществует несколько методов управления потоками. Давайте рассмотрим метод переводящий

рассмотрим метод переводящий поток в состояние ожидания.

Для этого

у класса «TimeUnit» выберем метод отвечающий за размерность времени, например «TimeUnit.MICROSECONDS», у этого метода есть метод «sleep», которому в качестве параметра нужно передать число, отвечающее за величину второго параметра(время проведенное в ожидании).

При реализации данного метода его необходимо поместить в блок try-catch.

2011 © EPAM Systems, RD Dep.


Слайд 95 Сoncurrent. Example 14
2011 © EPAM Systems, RD Dep.
package

Сoncurrent. Example 142011 © EPAM Systems, RD Dep.package timeunit;import java.util.concurrent.Callable;import java.util.concurrent.TimeUnit;public

timeunit;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
public class MyThread implements Callable {
public int

count = 0;
public Integer call() {
for (int i = 0; i < 1000000; i++) {
count++;
try {
TimeUnit.MICROSECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return count;
}
}

Слайд 96 Сoncurrent
Механизм управления мьютексами Lock

Lock является явным механизмом управления

СoncurrentМеханизм управления мьютексами LockLock является явным механизмом управления мьютексами. Он находиться

мьютексами. Он находиться в библиотеке java.util.concurrent.

Объект класса Lock

можно явно создать в программе и установить или снять блокировку с помощью его методов.

К плюсам данного объекта можно отнести возможность отлавливания исключений и другие.

Рассмотрим реализацию Lock для класса MyTread.

2011 © EPAM Systems, RD Dep.


Слайд 97 Сoncurrent. Example 15
2011 © EPAM Systems, RD Dep.
package

Сoncurrent. Example 152011 © EPAM Systems, RD Dep.package _java._se._07._concurrent;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public

_java._se._07._concurrent;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockDemo implements Runnable{
public static int

count;
private static Lock lock = new ReentrantLock();

public void run() {
for (int i = 0; i < 10000000; i++) {
lock.lock();
count++;
lock.unlock();
}
System.out.println(count);
}

public static void main(String[] args){
LockDemo lock1 = new LockDemo();
LockDemo lock2 = new LockDemo();
Thread th1 = new Thread(lock1);
Thread th2 = new Thread(lock2);

th1.start();
th2.start();
}
}

Слайд 98 Сoncurrent
Атомарные операции. Volatile

Атомарные операции- это операции, которые не

СoncurrentАтомарные операции. VolatileАтомарные операции- это операции, которые не могут быть прерваны

могут быть прерваны планировщиком потоков. Чтение и запись примитивных

переменных кроме double и long являются атомарными. Даже если операция является атомарной, значение переменной может хранится в кэше ядра, и быть не видным другому потоку, поэтому для обеспечение видимости внутри приложения существует ключевое слово volatile. Но данное ключевое слово не обеспечивает атомарности операциям, не смотря на то что после записи, значение поле будет отображено сразу при всех операциях чтения. Так что приведенный код все еще содержит ошибку некорректного доступа.

2011 © EPAM Systems, RD Dep.

public class MyThread implements Runnable {
public static volatile int count;
public void run() {
for (int i = 0; i < 10000000; i++) {
count++;
}
System.out.println(count);
}
}


Слайд 99 Сoncurrent. Example 16
Атомарные классы

Попробуем разрешить конфликт с помощью

Сoncurrent. Example 16Атомарные классыПопробуем разрешить конфликт с помощью атомарных классов: AtomicInteger,

атомарных классов: AtomicInteger, Atomic Long ,AtomicReference и т.д. Данный

класс гарантирует атомарное выполнение операций.


2011 © EPAM Systems, RD Dep.

package atomic;
import java.util.concurrent.atomic.AtomicInteger;
public class MyThread implements Runnable {
public static AtomicInteger count = new AtomicInteger(0);
public void run() {
for (int i = 0; i < 10000000; i++) {
// count.incrementAndGet();
// count.addAndGet(1);
count.getAndAdd(1);
}
System.out.println(count);
}
}


Слайд 100 Сoncurrent. Example 17
Синхронизованные коллекции


2011 © EPAM Systems, RD

Сoncurrent. Example 17Синхронизованные коллекции2011 © EPAM Systems, RD Dep.package _java._se._07._concurrent;import java.util.Random;import

Dep.
package _java._se._07._concurrent;
import java.util.Random;
import java.util.concurrent.PriorityBlockingQueue;
class Task implements Comparable {
private int

taskNumer;
public Task(int num) {
taskNumer = num;
}
public int getTaskNumer() {
return taskNumer;
}
public void setTaskNumer(int taskNumer) {
this.taskNumer = taskNumer;
}
@Override
public int compareTo(Task o) {
Random rand = new Random();
int comp = rand.nextInt(2000);
if (comp % 2 == 0) return 1;
if (comp % 3 == 0) return -1;
else return 0;
}
}

Слайд 101 Сoncurrent. Example 17
2011 © EPAM Systems, RD Dep.
class

Сoncurrent. Example 172011 © EPAM Systems, RD Dep.class Manager implements Runnable

Manager implements Runnable {
private QueueTask pbQ;
private String name;
public Manager(QueueTask

q, String n) {
pbQ = q;
name = n;
}
public void run() {
Task task;
while ((task = pbQ.getTask()) != null) {
System.out.println(name + " get task number " + task.getTaskNumer());
}
}
}

Слайд 102 Сoncurrent. Example 17
2011 © EPAM Systems, RD Dep.
class

Сoncurrent. Example 172011 © EPAM Systems, RD Dep.class QueueTask{	private PriorityBlockingQueue queue

QueueTask{
private PriorityBlockingQueue queue = new PriorityBlockingQueue();
public Task getTask() {
return

queue.poll();
}

public void setTask(Task task) {
queue.add(task);
}
public PriorityBlockingQueue getQueue() {
return queue;
}
}

Слайд 103 Сoncurrent. Example 17
2011 © EPAM Systems, RD Dep.
public

Сoncurrent. Example 172011 © EPAM Systems, RD Dep.public class PriorityBlockingQueueDemo {	public

class PriorityBlockingQueueDemo {
public static void main(String[] args) {
QueueTask pbQueue

= new QueueTask();
for (int i = 0; i < 10; i++) {
pbQueue.setTask(new Task(i));
}

Manager manager1 = new Manager(pbQueue, "Jonh");
Manager manager2 = new Manager(pbQueue, "Pol");

Thread th1 = new Thread(manager1);
Thread th2 = new Thread(manager2);

th1.start();
th2.start();

try {
th1.join();
th2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Слайд 104 Сoncurrent. Example 17
Результат:
2011 © EPAM Systems, RD Dep.
Jonh

Сoncurrent. Example 17Результат:2011 © EPAM Systems, RD Dep.Jonh get task number

get task number 2
Jonh get task number 8
Jonh get

task number 7
Pol get task number 3
Jonh get task number 0
Pol get task number 5
Pol get task number 6
Pol get task number 4
Pol get task number 9
Jonh get task number 1

Слайд 105 Сoncurrent. Example 17
А вот возможный результат использования в

Сoncurrent. Example 17А вот возможный результат использования в этом примере PriorityQueue2011

этом примере PriorityQueue
2011 © EPAM Systems, RD Dep.
Jonh get

task number 6
Pol get task number 6
Pol get task number 7
Pol get task number 2
Pol get task number 0
Pol get task number 4
Pol get task number 1
Pol get task number 5
Pol get task number 9
Jonh get task number 3

  • Имя файла: javase07-multithreading.pptx
  • Количество просмотров: 131
  • Количество скачиваний: 0