кодесурса

Взаимодействие Java-потоков

script1adsense2code
script1adsense3code

Вступление

Класс Object имеет три метода: wait (), notify () и notifyAll (), которые помогают потокам сообщать о состоянии события, о котором заботятся потоки. В последнем уроке мы видели о синхронизации ресурсов, где один поток может получить блокировку, которая заставляет другие потоки ожидать доступности блокировки. Класс объекта имеет эти три метода для связи между потоками.

Например, у нас есть два потока с именами car_owner и car_meachanic, если поток car_mechanicis занят, поэтому поток car_owner должен ждать и постоянно проверять, чтобы поток car_mechanic освободился. Используя механизм ожидания и уведомления, car_owner для служебного потока может проверять наличие car_mechanic, а если он не находит ничего, он может сказать: «Эй, я не собираюсь тратить свое время на проверку каждые несколько минут. Я собираюсь потусоваться, и когда car_mechanic выйдет на свободу, пусть он уведомит меня, чтобы я мог вернуться в runnable и выполнить некоторую работу ». Другими словами, использование wait () и notify () позволяет одному потоку поставить себя в «комнату ожидания», пока какой-то другой поток не уведомит его о том, что есть причина возвращаться.

Подпись метода Описание
final void wait () создает исключение InterruptedException Вызов этого метода приведет к тому, что вызывающий поток будет отключен от монитора и перейдет в спящий режим, пока какой-нибудь другой поток не войдет в тот же монитор и не вызовет метод notify ().
окончательное уведомление о недействительности () Этот метод похож на notify (), но он пробуждает все потоки, которые находятся в ожидании состояния для блокировки объекта, но только один поток получит доступ к блокировке объекта.

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

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

Ниже программа объясняет концепцию очереди автосервиса, где поток car_owner и car_mechanic взаимодействуют друг с другом в цикле.

Java-код:

package threadcommunication;
public class CarOwner implements Runnable {
	CarQueueClass q;
	CarOwner(CarQueueClass queue){
		this.q=queue;
		new Thread(this, "CarOwner").start();
	}
	@Override
	public void run() {
		int count =0;
		try {			
			while(count< 5){
				Thread.sleep(2000);
				q.put(count++);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

package threadcommunication;
public class CarMechanic implements Runnable {
	CarQueueClass q;
	CarMechanic(CarQueueClass queue){
		this.q=queue;
		new Thread(this, "CarMechanic").start();
	}
	@Override
	public void run() {
		for(int i=0;i< 5;i++)	
		q.get();
	}
}

package threadcommunication;
public class CarQueueClass {
		   int n;
		   boolean mechanic_available = false;
		   synchronized int get() {
		      if(!mechanic_available)
		      try {
		         wait(5000);
		      } catch(InterruptedException e) {
		         System.out.println("InterruptedException caught");
		      }
		      System.out.println("Got Request for Car Service: " + n);
		      mechanic_available = false;
		      notify();
		      return n;
		   }
		   synchronized void put(int n) {
		      if(mechanic_available)
		      try {
		         wait(5000);
		      } catch(InterruptedException e) {
		         System.out.println("InterruptedException caught");
		      }
		      this.n = n;
		      mechanic_available = true;
		      System.out.println("Put Request for Car Service: " + n);
		      notify();
		   }
}

package threadcommunication;
public class CarServiceDemo {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		 CarQueueClass q = new CarQueueClass();
	      new CarOwner(q);
	      new CarMechanic(q);
	      System.out.println("Press Control-C to stop.");
	}
}

Выход:


Резюме:

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

Редактор кода Java:

Предыдущая: Состояния потоков Java и переходы
Далее: Синхронизация кода Java

Новый контент: Composer: менеджер зависимостей для PHP , R программирования


script1adsense4code
script1adsense5code
disqus2code
script1adsense6code
script1adsense7code
script1adsense8code
buysellads2code