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


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

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



Многопоточность – это реализация процесса на основе параллельно выполняющихся потоков.

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

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

Правила переключения между потоками:

1) добровольный отказ от управления (кооперация) – это явный переход в режим ожидания или передача управления самому высокоприоритетному потоку, готовому к выполнению, но при этом исходный поток блокируется;

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

 

Лекция 9

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

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

Семафор – это механизм управления связью между процессами. Это блок, который может использоваться только одним потоком. В Java нет определенного класса объектов типа семафор. Семафоры еще называют мониторами.

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

Некоторые методы класса Thread() (класс, который используется для создания потоков):

getName() – получить имя потока;

getPriority() – получить приоритет потока;

isAlive() – определить, выполняется ли еще поток;

join() – ждать завершение потока;

run() – указать точку входа в поток;

sleep() – остановить поток на определенный период времени;

start() – запустить поток с помощью вызова его метода run();

 

Организация потоков

Диапазон приоритетов потоков определяется: MIN_PRIORITY – 1 и MAX_PRIORITY – 10. По умолчанию приоритет потока равен 5. При запуске main-функции её приоритет по умолчанию равен 5.

Один из потоков (главный или родительский) начинает выполняться первым при запуске Java-программы. От главного потока определяются дочерние потоки. Главный поток начинает выполняться первым и заканчивает выполнятся последним. Программа завершается, когда главный поток останавливается.

Поток может быть создан на основе базового класса Thread или реализации интерфейса Runnable. Класс Thread инкапсулирует ряд методов, которые помогают управлять потоками. Главный поток создаётся автоматически с именем main и приоритетом 5 по умолчанию. Им можно управлять через объект класса Thread. Ссылку на него можно получить, используя статический метод:

 

static currentThread().

 

Пример:

 

Thread th = Thread.currentThread(); /*возвращает ссылку на

поток, в котором он вызывается. В

дальнейшем эту объектную ссылку

можно использовать для вызова

методов управления потоками */

 

Создание нового потока

Самый простой способ создания потока – это реализация интерфейса Runnable, внутри которого определен единственный метод: public void run(). При создании потока (при реализации интерфейса Runnable) в классе требуется реализация метода run():

 

class A implements Runnable

{ ….

run();

……}

 

Пример: класс, реализующий многопоточность

 

class NewThread implements Runnable

{Thread t;

NewThread (); //конструктор для создания нового потока

{ t = new Thread(this, “DemoThread”);

System.out.println(“Дочерний поток ”+t);

t.start(); //стартовать поток

}

public void run()

{ try { for(int i=3; i>0; i--)

{ System.out.println(“Дочерний поток: ”+i);

Thread.sleep(500); //приостановить поток на 500 мс

}

}

catch(Exception e)

{ System.out.println(“Прерывание дочернего потока”);}

System.out.println(“Завершение дочернего потока ”);

} }

//головная программа

class ThreadDemo

{ public static void main(String args[])

{ new NewThread ();

try { for(int i=3; i>0; i--)

{ System.out.println(“Главный поток “);

Thread.sleep(500);

}

}

catch(Exception e)

{ System.out.println(“Прерывание главного потока”);}

System.out.println(“Завершение главного потока ”);

} }

 

Вывод программы:

Дочерний поток: Thread [DemoThread, 5, main]

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

Дочерний поток 3

Дочерний поток 2

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

Дочерний поток 1

Завершение дочернего потока

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

Завершение главного потока

За счет расчета величины паузы 1000 и 500 мс обеспечивается завершение главного потока после дочернего.

Синхронизация предназначена для разграничения и упорядочивания доступа нескольких потоков к разделяемому ресурсу (напр., таблица БД, файл, статическая переменная).

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

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

1) синхронизация метода – если критическим участком является метод, то можно просто указать ключевое слово synchronized.

Пример:

 

synchronized void myMethod()

{……}

или

void myMethod()

{ synchronized(this)

{…….}

}

 

2)синхронизация объекта – если нет доступа к классу, в котором объявлен метод, то для его синхронизации можно использовать следующий приём:

 

synchronized(Object)

{ //операторы критического участка, в том числе и вызовы метода

}

 

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

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

 

 



Поделиться:


Последнее изменение этой страницы: 2017-02-09; просмотров: 99; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.238.62.119 (0.027 с.)