Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОТВЕТЫ МИР.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
546.82 Кб
Скачать

44 Создание потока. Синхронизация потоков в Java

Поток создается с помощью объекта класса Thread, при этом есть 2 способа:

1. реализация интерфейса Runnable

2. расширение класса Thread

1) Самый легкий путь – создать класс, который реализует интерфейс Runnable. В этом классе достаточно реализовать только метод Run, в котором помещаются операторы, предназначенные для выполнения в новом потоке, причем этот же метод Run может вызывать другие методы, использовать классы и объявлять свои переменные.

С помощью объявления метода Run создается точка входа другого (конкурирующего) потока, выполнение которого заканчивается при завершении метода run. После создания класса, который реализует интерфейс Runnable, необходимо создать экземпляр объекта Thread внутри этого класса. Один из конструкторов имеет следующий вид: Thread (Runnable «объект потока», String «имя потока»);

Объект потока – это ссылка на экземпляр класса, реализованный в интерфейсе Runnable. С помощью этого значения определяется точка входа для выполнения данного потока. Поток не будет выполняться, пока не будет вызван метод start() класса Thread этот метод и предназначен для вызова метода run.

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

Thread t;

t = new Thread(this, «поток»);

Передача в качестве параметра ссылки this показывает, что надо создавать поток, который будет вызывать метод run данного объекта.

2) При реализации расширением класса Thread, во-первых, необходимо создать новый класс Thread, а потом создать экземпляр данного класса. В созданном классе необходимо перекрыть метод run, который является точкой входа для нового потока. Кроме этого, в конструкторе необходимо вызвать метод start для запуска потока.

Пример:

class Thread1 implements Runnable{

Thread t;

Thread1(){t = new Thread(this, «поток»);t.start();}

public void run(){

try{

for (int I = 5; i>0; i--){Thread.sleep(500);}

}catch (InterruptedException e){}

}}

class Thread2 extends Thread{

Thread2(){ super(«поток»);start();}

(------ метод run() аналогичен -----)

}

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

isAlive() – возвращает true, если поток выполняется

join() – ожидает завершения потока, к которому принадлежит.

suspend(), resume() – приостановка и возобновление выполнения потока соответственно.

Синхронизация потоков.

Для решения задач синхронизации 2х и более потоков используется концепция монитора. Это объект, который используется как взаимная блокировка. Лишь один класс может занимать монитор в данное время. Ключевое слово synchronized используется как модификатор доступа при описании методов, доступ к которым следует синхронизировать. public synchronized void decrement() { . . .}

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

synchronized(Account){

if(Account.check(3000000))

Account.decrement(3000000);}

Здесь синхронизация выполняется для объекта Account.