Elettracompany.com

Компьютерный справочник
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Java object wait

How to work with wait(), notify() and notifyAll() in Java?

By Lokesh Gupta | Filed Under: Java Concurrency

Java concurrency is pretty complex topic and requires a lot of attention while writing application code dealing with multiple threads accessing one/more shared resources at any given time. Java 5, introduced some classes like BlockingQueue and Executors which take away some of the complexity by providing easy to use APIs.

Programmers using concurrency classes will feel a lot more confident than programmers directly handling synchronization stuff using wait(), notify() and notifyAll() method calls. I will also recommend to use these newer APIs over synchronization yourself, BUT many times we are required to do so for various reasons e.g. maintaining legacy code. A good knowledge around these methods will help you in such situation when arrived.

In this tutorial, I am discussing the purpose of wait() notify() notifyall() in Java. We will understand the difference between wait and notify.

1. What are wait(), notify() and notifyAll() methods?

The Object class in Java has three final methods that allow threads to communicate about the locked status of a resource.

It tells the calling thread to give up the lock and go to sleep until some other thread enters the same monitor and calls notify() . The wait() method releases the lock prior to waiting and reacquires the lock prior to returning from the wait() method. The wait() method is actually tightly integrated with the synchronization lock, using a feature not available directly from the synchronization mechanism.

In other words, it is not possible for us to implement the wait() method purely in Java. It is a native method.

General syntax for calling wait() method is like this:

notify()

It wakes up one single thread that called wait() on the same object. It should be noted that calling notify() does not actually give up a lock on a resource. It tells a waiting thread that that thread can wake up. However, the lock is not actually given up until the notifier’s synchronized block has completed.

So, if a notifier calls notify() on a resource but the notifier still needs to perform 10 seconds of actions on the resource within its synchronized block, the thread that had been waiting will need to wait at least another additional 10 seconds for the notifier to release the lock on the object, even though notify() had been called.

General syntax for calling notify() method is like this:

notifyAll()

It wakes up all the threads that called wait() on the same object. The highest priority thread will run first in most of the situation, though not guaranteed. Other things are same as notify() method above.

General syntax for calling notify() method is like this:

Let’s write a small program to understand how wait(), notify(), notifyall() methods should be used to get desired results.

2. How to use with wait(), notify() and notifyAll() methods

In this exercise, we will solve producer consumer problem using wait() and notify() methods. To keep program simple and to keep focus on usage of wait() and notify() methods, we will involve only one producer and one consumer thread.

Other features of the program are :

  • Producer thread produce a new resource in every 1 second and put it in ‘taskQueue’.
  • Consumer thread takes 1 seconds to process consumed resource from ‘taskQueue’.
  • Max capacity of taskQueue is 5 i.e. maximum 5 resources can exist inside ‘taskQueue’ at any given time.
  • Both threads run infinitely.

2.1. Producer Thread

Below is the code for producer thread based on our requirements :

  • Here “ produce(counter++) ” code has been written inside infinite loop so that producer keeps producing elements at regular interval.
  • We have written the produce() method code following the general guideline to write wait() method as mentioned in first section.
  • Once the wait() is over, producer add an element in taskQueue and called notifyAll() method. Because the last-time wait() method was called by consumer thread (that’s why producer is out of waiting state), consumer gets the notification.
  • Consumer thread after getting notification, if ready to consume the element as per written logic.
  • Note that both threads use sleep() methods as well for simulating time delays in creating and consuming elements.

2.2. Consumer Thread

Below is the code for consumer thread based on our requirements :

  • Here “ consume() ” code has been written inside infinite loop so that consumer keeps consuming elements whenever it finds something in taskQueue.
  • Once the wait() is over, consumer removes an element in taskQueue and called notifyAll() method. Because the last-time wait() method was called by producer thread (that’s why producer is in waiting state), producer gets the notification.
  • Producer thread after getting notification, if ready to produce the element as per written logic.

2.3. Test producer consumer example

Now lets test producer and consumer threads.

I will suggest you to change the time taken by producer and consumer threads to different times, and check the different outputs in different scenario.

3. Interview questions on wait(), notify() and notifyAll() methods

3.1. What happens when notify() is called and no thread is waiting?

In general practice, this will not be the case in most scenarios if these methods are used correctly. Though if the notify() method is called when no other thread is waiting, notify() simply returns and the notification is lost.

Since the wait-and-notify mechanism does not know the condition about which it is sending notification, it assumes that a notification goes unheard if no thread is waiting. A thread that later executes the wait() method has to wait for another notification to occur.

3.2. Can there be a race condition during the period that the wait() method releases OR reacquires the lock?

The wait() method is tightly integrated with the lock mechanism. The object lock is not actually freed until the waiting thread is already in a state in which it can receive notifications. It means only when thread state is changed such that it is able to receive notifications, lock is held. The system prevents any race conditions from occurring in this mechanism.

Similarly, system ensures that lock should be held by object completely before moving the thread out of waiting state.

3.3. If a thread receives a notification, is it guaranteed that the condition is set correctly?

Simply, no. Prior to calling the wait() method, a thread should always test the condition while holding the synchronization lock. Upon returning from the wait() method, the thread should always retest the condition to determine if it should wait again. This is because another thread can also test the condition and determine that a wait is not necessary — processing the valid data that was set by the notification thread.

Читать еще:  Ошибка 0xc000007b battlefield 4

This is a common case when multiple threads are involved in the notifications. More particularly, the threads that are processing the data can be thought of as consumers; they consume the data produced by other threads. There is no guarantee that when a consumer receives a notification that it has not been processed by another consumer.

As such, when a consumer wakes up, it cannot assume that the state it was waiting for is still valid. It may have been valid in the past, but the state may have been changed after the notify() method was called and before the consumer thread woke up. Waiting threads must provide the option to check the state and to return back to a waiting state in case the notification has already been handled. This is why we always put calls to the wait() method in a loop.

3.4. What happens when more than one thread is waiting for notification? Which threads actually get the notification when the notify() method is called?

It depends on many factors.Java specification doesn’t define which thread gets notified. In runtime, which thread actually receives the notification varies based on several factors, including the implementation of the Java virtual machine and scheduling and timing issues during the execution of the program.

There is no way to determine, even on a single processor platform, which of multiple threads receives the notification.

Just like the notify() method, the notifyAll() method does not allow us to decide which thread gets the notification: they all get notified. When all the threads receive the notification, it is possible to work out a mechanism for the threads to choose among themselves which thread should continue and which thread(s) should call the wait() method again.

3.5. Does the notifyAll() method really wake up all the threads?

Yes and no. All of the waiting threads wake up, but they still have to reacquire the object lock. So the threads do not run in parallel: they must each wait for the object lock to be freed. Thus, only one thread can run at a time, and only after the thread that called the notifyAll() method releases its lock.

3.6. Why would you want to wake up all of the threads if only one is going to execute at all?

There are a few reasons. For example, there might be more than one condition to wait for. Since we cannot control which thread gets the notification, it is entirely possible that a notification wakes up a thread that is waiting for an entirely different condition.

By waking up all the threads, we can design the program so that the threads decide among themselves which thread should execute next. Another option could be when producers generate data that can satisfy more than one consumer. Since it may be difficult to determine how many consumers can be satisfied with the notification, an option is to notify them all, allowing the consumers to sort it out among themselves.

Как использовать wait()/notify() в Java

Я знаю, что есть несколько открытых тем по этой теме, но я просто ищу очень простой пример того, как использовать wait() и notify() в Java. Под «VERY ELEMENTARY,» я подразумеваю просто распечатку чего-то. Спасибо.

EDIT: вот что я пробовал до сих пор, и я получаю IllegalMonitorStateException:

6 Ответов

wait и notify используются в синхронизированном блоке при использовании потоков для приостановки и возобновления там, где они были прерваны.

Wait немедленно освобождает замок, в то время как Nofity покинет замок только тогда, когда встретится концевая скобка.

Ваш IllegalMonitorStateException связан с тем, что вы должны синхронизировать на объекте перед вызовом wait или notify. Так

Ваш пример не будет работать, потому что вы никогда не доберетесь до вызова notify . как только ваша нить ударит по ожиданию, она приостановится и не продвинется дальше. Для работы wait / notify необходимо иметь два потока. Один поток приостанавливается при вызове метода wait , и в конечном итоге второй поток вызывает synchronized(this) < this.notify() >, чтобы заставить первый поток проснуться и продолжить выполнение ниже вызова ожидания.

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

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

Теперь порядок вызовов метода не имеет значения. Если вы сначала уведомите об этом, ни один поток не проснется, но это нормально, потому что вы не собираетесь спать, так как isReady = true. Если вы ложитесь спать первым, isReady = true ничего не делает, но вызов notify будит поток. Наконец, синхронизация гарантирует, что вы не проверяете переменную в потоке A, затем поток B устанавливает переменную и уведомляет (ничего не делая), а затем поток A засыпает и никогда не просыпается.

Надеюсь, это поможет.

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

Основная идея этих функций заключается в том, что wait() приостанавливает поток (переводит его в спящий режим), а notify() заставляет поток возвращаться туда, откуда он ушел, когда он заснул.

Взгляните на: это или просто посмотрите simple prodcuer consumer problem java в google. Я уверен, что вы найдете что-нибудь подходящее для ваших нужд.

Смотрите этот пример на защищенных блоках с сайта oracle java — он включает в себя отработанный пример простой проблемы производителя-потребителя .

Похожие вопросы:

Это не дубликат Java, многопоточность с синхронизированными методами . он не задал того же вопроса. Я пытаюсь написать программу, которая использует многопоточность и взаимоблокировки. У меня.

Как я понимаю, я должен вызвать wait() на mutex, когда я хочу, чтобы текущий поток перестал работать, пока другой поток не вызовет notify() на том же объекте mutex. Это, кажется, не работает. Я.

Есть ли какая-либо замена wait / notify в java ? У меня есть две темы: thread1: run() < while(true) < data = getDataFromDatabase() changedData = performSomeChanges(data).

Читать еще:  Java lang string что это

Я пытаюсь понять, как работают методы Java wait и notify . Согласно документации, wait() заставляет поток ждать последующих вызовов методов notify() или notifyAll() , но по какой-то причине notify.

У меня работает экземпляр nifi 1.2.0. Я просто попытался использовать процессор WaitNotify со следующей ссылкой http://ijokarumawak.github.io/nifi/2017/02/02/nifi-notify-batch /.

Возможный Дубликат : Почему wait() и notify() объявлены в классе объектов Java’s? Мне было интересно, почему notify() , notifyAll() и wait() методы присутствуют в классе объектов, в то время как.

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

Выяснив, как использовать wait() и notify() в приложении Java для извлечения некоторых данных из интернета, мне пришлось перенести этот код в мое приложение Android. Как оказалось, код, который.

Java — Thread Communication using wait/notify

It is common in multithreaded programming to require one thread to wait for another thread to take some action.

Semantically, there’s no direct thread communication possible as per underlying thread model, instead a developer can use some condition based on a shared variable to achieve the inter-thread communication.

Let’s consider following example where the thread1 prints a message while thread2 populates the same message string:

Due to thread scheduler unpredictability, we cannot guarantee that thread1 will print the message populated by thread2. There must be some mechanism for thread1 to signal thread2 that shared message has been populated. Following is the most common solution a developer can come up with:

The above thread1’s while loop is known as ‘Guarded Blocks’, but that’s not an efficient solution as this loop is just wasting CPU cycles also we cannot avoid thread interference .

Java extends it’s ‘intrinsic lock’ model to provide a better solution, i.e. by using java.lang.Object methods wait() and notify()/notifyAll().

All these Object’s method calls are redirected to native methods, that means this mechanism is inherently provided by underlying operating system.

Let’s modify above example to see how that works:

Object.wait() and Object.notify()

wait() causes the current thread to wait (blocks or suspends execution) until another thread invokes the notify() method or the notifyAll() method for this object.

wait() method throws InterruptedException — If the corresponding thread calls interrupt() then the waiting state will get interrupted (just like sleep() method). The interrupted status of the current thread is cleared when this exception is thrown.

Unlike sleep method which doesn’t release the ‘intrinsic lock’, this method releases the ‘intrinsic lock’. That means other threads have opportunity to execute other synchronized blocks/methods while this thread is in waiting state, which is good for overall performance.

Also this method call will throw IllegalMonitorStateException if the current thread is not the owner of the object’s monitor (the intrinsic lock). That’s the reason we used synchronized block in the above example.

In above example, we can also use synchronized methods instead. Let’s modify above example to consolidate synchronization and thread communication to a single object:

notify() vs notifyAll()

notify() wakes up a single thread that is waiting on this object’s monitor (intrinsic lock). If multiple threads are waiting then only one of them will get notified or will wake up; which thread will be notified, we cannot predict, that totally depends on the scheduler.

notifyAll() will cause all threads to wake up if they are in waiting state due to wait() call.

Since notify() and notifyAll() are also called from synchronized method/blocks: waiting thread will not start executing till the thread which calls these methods releases the lock.

Java Thread: notify() and wait() examples

This article contains two code examples to demonstrate Java concurrency. They stand for very typical usage. By understanding them, you will have a better understanding about notify() and wait().

1. Some background knowledge

  1. synchronized keyword is used for exclusive accessing.
  2. To make a method synchronized, simply add the synchronized keyword to its declaration. Then no two invocations of synchronized methods on the same object can interleave with each other.
  3. Synchronized statements must specify the object that provides the intrinsic lock. When synchronized(this) is used, you have to avoid to synchronizing invocations of other objects’ methods.
  4. wait() tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify( ).
  5. notify() wakes up the first thread that called wait() on the same object.

2. notify() and wait() — example 1

in example 1 : if the object is another type of object(another class or user defined object) it works well.But in this example thread is used so we can’t say when the thread executes . wait function may be executed before or after the thread calls its depends on system speed. So here we cant use threads if u use threads u can use these methods thread.isAlive(),thread.join() and thread.isDaemon() for checking the thread executed or running.

Example#1 is really bad example. If `notify()` invokes before `b.wait()`, then you get a deadlock.

Because Main thread itself gets ‘Blocked on Monitor’ and So, there is no thread to start the b thread.

Hello friends!
I am an official representative of private company which deals with all kinds of written work (essay, coursework, dissertation, presentation, report, etc) in short time.
We are ready to offer a free accomplishment of written work hoping for further cooperation and honest feedback about our service.
Send your work topics to our email: [email protected] . This offer has limited quantities.

Agree. Adding a “Thread.sleep(4000);” right after “b.start()” would demonstrate it.

Can somebody please explain why in example 1, if I move b.start(); to below the synchronized(b) block, the output is always “Waiting for b to complete…”?

synchronized(b) <
try <
System.out.println(“Waiting for b to complete…”);
b.wait();
> catch(InterruptedException e) <
e.printStackTrace();
>
System.out.println(“Total is: ” + b.total);
>
b.start();

Output: “Waiting for b to complete…”

SInce b.wait() inside the block would release the lock and wait, why didn’t the program continue with b.start() and complete, so that the block can continue?

Please delete this shit so others won’t waste their time

My take on the first example. Added a sleep to simulate a notify too before the wait and a condition check to avoid thread lock:

public class ThreadA <
public static void main(String[] args) <
ThreadB b = new ThreadB();
b.start();
try <
Thread.sleep(1000); // simulate a notify() before the wait()
>
catch (InterruptedException e) <

Читать еще:  Java lang illegalstateexception что это

>
synchronized(b) <
try <
System.out.println(“Waiting for b to complete…”);
while (b.isAlive()) < //condition guarantees no thread lock occurs
b.wait();
>
>catch(InterruptedException e) <
e.printStackTrace();
>

System.out.println(“Total is: ” + b.total);
>
>
>

class ThreadB extends Thread <
int total;
@Override
public void run() <
synchronized(this) <
for(int i=0; i Rahul

Why we should always call wait method in loop

know how to you satisfy yahoo offer us an case in point of a accurate instance 1 by means of Runnable?

It looks like in example#2 code in getMessage() is broken… notify() method call is too early which’ll wake up thread(s) already in m’s waitSet ( which exactly is thread called putMessage() ). notify() should be places at the end of getMessage() method.

Can you please provide us an example of a correct Example 1 using Runnable?

Yes, you can try this example and once a while it will lock up.

> Below is example of wait notify 1st customer is trying to withdrawal
> money 2000 but account is having only 1000 Rs so wait for deposit,
> once deposit is completed then customer will able to withdrawal
> amount ..till deposit customer is waiting.

private int totalAmount=1000;

public synchronized void deposite(int amount) <
System.out.println(«Depositing amount «+amount);
this.totalAmount+=amount;
System.out.println(«deposit completed…and Now totalAmount is «+this.totalAmount);
notify();
>
>

class Depo implements Runnable <
Cust c; int depo;
Depo(Cust c, int depo) <
this.c=c;
this.depo=depo;

@Override
public void run() <
c.deposite(depo);

>
class Withdrawl implements Runnable <
Cust c; int with;
Withdrawl(Cust c, int with) <
this.c=c;
this.with=with;

@Override
public void run() <
c.withdrwl(with);

public class MainClass <

public static void main(String[] args) <
Cust c = new Cust();
Thread w = new Thread(new Withdrawl(c, 2000));
Thread d= new Thread(new Depo(c, 1000));
w.start();
d.start();

I agree. You should use b.join(); which will force the main thread to wait until the calculation is complete

this is perfect for example #1 to understand more on wait()

Quick hack: In that case, we can avoid wait “forever” with “b.wait(someTime)”.

call to wait() method should be with in a loop that checks the condition on which the thread is waiting. That’s a recommendation as per java docs to avoid a scenario known as spurious wakeup.

This example won’t work if notify() is called before wait() is called . If it is the case, then main thread will wait/block forever . To make sure wait() is called 1st then before b.start() , we issue wait() command . Am I right ?

“b.wait()” will cause the current thread (i.e. the main thread) to wait until another thread has called one of the notify-methods of “b”. Since no other thread has access to “b”, other than “b” itself, the main thread will wait “forever”.

Looks fine form me ,
main thread will start, then thread b will start and get the lock then completes its calculation. After that second block of synchronization will start and after printing “waiting for the thread b to complete….” it will call .wait() method to release the lock. Then again normal main thread will execute and prints the total.
But I wanted a more complex example so that we can understand more . This is very simple example and not elaborating much

Помогите с wait / notify / notifyall

Базовые технологии Java /

Нити и процессы

Я что-то понять не могу, если у меня есть класс

Wait приостановит выполнение, а что значит когда я wait вызываю на объекте, кого он приостанавливает .

Ну и соответственно Кого будит это строчка, если я ее на объекте вызываю? Какой поток? Т.е.

Да и еще есть метод notifyAll() , допустим 500 потоков с наивысшим приоритетом находится в wait , если
я вызову notify, то какой из этих 500 проснется, notifyAll всех их пробудит по ходу, так что ли?

Плюс я баловался вчера с такими классами:

Можно наглядно увидеть кто кого блокирует

Я что-то понять не могу, если у меня есть класс

Wait приостановит выполнение, а что значит когда я wait вызываю на объекте, кого он приостанавливает .

В обоих случаях приостанавливается текущий поток (currentThread()). В первом случае текущий поток совпадает с объектом синхронизации, но это 2 разные роли, их необходимо различать.

Объясню на примере приостанавливаемого потока:

Не проще ли сделать

В вашем коде я даже не понимаю, как это должно работать. Как первый поток должен пройти через lock.wait() ?

Кто-то внешний будет вызывать lock.notify() для первого потока?

Разве можно вызывать wait() вне synchronized блока?

Не проще ли сделать

Вам было показано немного другое — тред с паузой. Вы же в doTask() хотите чтобы оба потока соревновались за монитор объекта lock. Да, отработает по очереди, но это другое.

Первый поток не вызывает wait(), он спит sleep(). Вот второй — да, освобождает монитор и уходит в wait.

Нет, перед wait нужно, чтобы текущий поток захватил монитор объекта.

Тут видите какая штука, неважно кто вызовет notify у объекта на котором висит тред, главное чтобы кто-то захватил монитор и освободил его методом notify или notifyAll.

Вот мне только не понятно, каким образом выбирается тред из списка ждущих если мы вызываем notify? Random?

Да, произвольно. Равно как и notifyAll высвобождает их в произвольном порядке.

Ага, точно! Спасибо. Вот нашел в доке:

То есть решение принимает runtime system на уровне операционки.

Добрый день.
В Java с каждым объектом ассоциирован монитор.
Состояние монитора — это
1) логический флажок — занято или нет
2) wait-set — множество «пассивных» потоков ждущих пробуждения (CPU не загружают)
2) blocked-set — множество «активных» потоков ждущих только возможности захватить монитор (CPU не загружают)

Метод notify() перемещает один из потоков из wait-set в blocked-set.
Метод notifyAll() перемещает все потоки из wait-set в blocked-set.

Поток помещается в wait-set объекта когда:
— сам вызывает метод wait у объекта
Поток помещается в blocked-set объекта когда
— вызывает synchronized метод/секцию, а монитор занят
— он счастливчик и os/jvm перемещает его из wait-set в blocked-set по notify(), а монитор занят
— по notifyAll() его среди всех остальных перемещают в blocked-set, а монитор занят
— он вошел в wait-set через использования одной из версий wait(. ) с таймаутом и таймаут истек
— сработал spirious wakeup и поток выбросило из wait-set в blocked-set

Спецификация не гарантирует никакого порядка
— ни при выборе по notify() одного из wait-set в blocked-set
— ни при захвате монитора потоками из blocked-set

Но в реальности os/jvm реализует какой-то порядок.

Демонстрация нахождения в wait-set:

Демонстрация нахождения в blocked-set:

Демонстрация порядка выбора по notify (у меня вывело » 0 1 2 3 4 5 6 7 8 9″)

Демонстрация порядка захвата монитора (у меня вывело » 9 8 7 6 5 4 3 2 1 0″)

Ссылка на основную публикацию
Adblock
detector