A simple wait() & notify() example - doesn't work - java

I tries to write a simple example that demonstrates a remote controller opertation.
The input is being accepted via the console, and a message is being printed accordingly.
Both threads run infinite loops: the main thread waits for notification, while the other waits for a console input.
I'd like to know how to fix it. The problem is that the notify doesn't stop the waiting: in other words, the words "before wait" are printed, but the words "after wait" are not. BTW, without the while(true) loops it works fine (for one button press).
Many thanks
public class MainTV {
public static int lastRemoteCode = 0;
public static void main(String[] args){
RemoteControllerThread remote = new RemoteControllerThread();
remote.start();
synchronized(remote){
while(true){
try {
System.out.println("before wait");
remote.wait();
System.out.println("after wait");
switch (lastRemoteCode){ //we use switch because there are many code options
case 0:
System.out.println("Error with remote button reading");
break;
case 3:
System.out.println("Volume Down button was pressed now!");
break;
case 4:
System.out.println("Volume Up button was pressed now!");
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
and the second class (simulates the remote controller):
import java.util.Scanner;
public class RemoteControllerThread extends Thread{
public void run(){
synchronized(this){
Scanner in = new Scanner(System.in);
while(true){
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
notify();
System.out.println("after notify");
}
}
}
}

Both threads synchronize on the same object, this refers to the same object as remote and since both this synchronize blocks have infinite loops inside, this creates a problem. One of the thread will wait for the other one to finish, which never happens (because of the infinite loops).
To fix this, you should synchronize only the code that needs to be synchronized, like the wait() and notify() calls.

I think there are two problems with your code.
When the main thread execution reaches synchronized(remote) it might not continue because the remote controller thread (possibly) already locked the remote object. Move remote.start() into synchronized(remote) block.
In order to let execution continue from wait you need to release the object lock after notify. Change syncronization block in thread like:
-
public void run() {
Scanner in = new Scanner(System.in);
while(true){
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
synchronized(this) {
notify();
}
System.out.println("after notify");
}
}

To quote from notify() JavaDoc:
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object
Your remote never lets go of the lock. If you switch the synchronized with the while, you have a slim chance, but usually you remote will get the lock back immediately. The following works, for instance:
class RemoteControllerThread extends Thread {
public void run() {
while (true) {
synchronized (this) {
Scanner in = new Scanner(System.in);
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
notify();
System.out.println("after notify");
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Related

What is the correct way to avoid an empty synchronized block?

Recently I've started looking into multithreading, and I have a question, perhaps more experienced ones could help.
My program creates two parallel threads, each of them prints counts from 0 to 19 (the NumbersPrinter class, which implements the Runnable interface).
class NumbersPrinter implements Runnable {
private Mediator mediator;
private String name;
private int makeActionOnCount;
public NumbersPrinter(Mediator mediator, String name, int makeActionOnCount) {
this.mediator = mediator;
this.name = name;
this.makeActionOnCount = makeActionOnCount;
}
#Override
public void run() {
for(int i = 0; i<20; i++){
try {
synchronized(this.mediator) {
if(this.mediator.actionInProgress.get()) {
System.out.println(name + " waits");
wait();
}
}
System.out.println(this.name + " says " + i);
Thread.sleep(500);
if(i == makeActionOnCount) {
synchronized(this.mediator) {
System.out.println(this.name + " asks Mediator to perform action...");
this.mediator.performAction();
this.mediator.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
When one of the threads reaches a certain number (defined in the makeActionOnCount variable), it starts performing a certain action that stops the execution of the second counter. The action lasts 5 seconds and after that both counters continue to count.
The counters are interconnected through an instance of the Mediator class, the performAcyion() method also belongs to the instance of the Mediator class.
import java.util.concurrent.atomic.AtomicBoolean;
class Mediator {
public AtomicBoolean actionInProgress = new AtomicBoolean(false);
public Mediator() {
}
public void performAction() throws InterruptedException {
actionInProgress.set(true);
System.out.println("Action is being performed");
Thread.sleep(5000);
System.out.println("Action has been performed");
actionInProgress.set(false);
}
}
Here's the Main class:
class Main {
public static void main(String[] args) throws InterruptedException{
Mediator mediator = new Mediator();
NumbersPrinter data = new NumbersPrinter(mediator, "Data", 10);
NumbersPrinter lore = new NumbersPrinter(mediator, "Lore", 5);
Thread oneThread = new Thread(data);
Thread twoThread = new Thread(lore);
System.out.println("Program started");
oneThread.start();
twoThread.start();
oneThread.join();
twoThread.join();
System.out.println("Program ended");
}
The way the program is written now - works fine, but I don't quite understand what exactly should I write in the first synchronized block, because if you delete all content from it, the program still works, since the counter that does not execute the performAction() method stops 'cause the counter cannot access the monitor of the Mediator object 'cause it is busy with the parallel counter. AtomicBoolean variable and checking it also makes no sense.
In other words, I may not use the wait () and notify () constructs at all, as well as the value of the AtomicBoolean variable, and just check access to the Mediator object's monitor every new iteration using an empty synchronized block. But I've heard that an empty synchronized block is a bad practice.
I am asking for help on how to rewrite the program to use the synchronized block and the wait() and notify() methods correctly.
Maybe I'm syncing on the wrong object? How would you solve a similar problem?
Thanks in advance

Pause Thread after a method is called

Basically I want to pause my Thread after I called a method, before continuing to the other one. I can't loop, my method can only be ran once.
The idea behind this, is to be used in a game, where the methods will display messages, and each time a user presses a key, the next message sould be shown. I can't just go through a list, as the game takes input from the user. I looket at Thread.pause() and Thread.resume() but they woN't work either, and are deprecated.
My current code (Which isn't working):
private Thread thread;
private Thread managerThread;
private final Object lock = new Object();
private boolean shouldThreadRun = true;
private boolean storyRunning = true;
public Storyline() {
setUpThread();
}
private void setUpThread() {
managerThread = new Thread(() -> {
while(storyRunning) {
synchronized (lock) {
if(!shouldThreadRun) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Looping");
}
}
});
thread = new Thread(() -> {
synchronized (lock) {
pauseThread();
System.out.print("A");
pauseThread();
System.out.print("B");
}
});
managerThread.start();
thread.start();
}
public void pauseThread() {
shouldThreadRun = false;
}
public void resumeThread() {
shouldThreadRun = true;
}
Take a look at my edits and see if it is any similar to what you were trying to achieve. I'm using a scanner to simulate user input, just press enter on your keyboard to try it out.
By the way I hope this is just an exercise and not a real life situation. You should try to avoid this kind of low level management of multithreading in a real product, unless really necessary, in which case you should still use appropriate data structures meant for this. In a real application buttons will be linked to callbacks and you will set some onClick() method to execute the code you need, as soon as the button is pressed.
For what concerns concurrency, I strongly suggest you to take a look at these tutorials: Oracle-Concurrency
PS: notice that I'm completely ignoring interrupts, which is a bad practice, those exception should be handled the right way: I was just trying to achieve the desired result by keeping the code as simple as possible. Also, like someone else pointed out, you should handle spurious wakeups by just calling the wait inside a loop.
private Thread thread;
private Thread managerThread;
private final Object lock = new Object();
Scanner in;
public Storyline() {
setUpThread();
}
private void setUpThread() {
managerThread = new Thread(() -> {
while(true) {
in = new Scanner(System.in);
in.nextLine();
resumeThread();
}
});
thread = new Thread(() -> {
synchronized (lock) {
while(true){
System.out.print("A");
try {
lock.wait();
} catch (InterruptedException e) {}
System.out.print("B");
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
});
managerThread.start();
thread.start();
}
public void resumeThread() {
synchronized(lock){
lock.notify();
}
}
The first rule of Object.wait, as described in the documentation, is that it must be called in a loop which depends on the condition which is the basis for the wait.
So, your wait needs to look like this:
synchronized (lock) {
while (!shouldThreadRun) {
lock.wait();
}
}
An interrupt is not something that happens by accident. A thread is only interrupted if another thread explicitly asks it to stop what it’s doing and exit cleanly.
Therefore, if you get an interrupt, the correct course of action is not to ignore it and print a stack trace. You need to exit cleanly.
The easiest way to do this is to simply enclose your entire while loop in a try/catch:
try {
while (storyRunning) {
synchronized (lock) {
while (!shouldThreadRun) {
lock.wait();
}
System.out.println("Looping");
}
}
} catch (InterruptedException e) {
System.out.println("Exiting, because someone asked me to stop.");
e.printStackTrace();
}
This way, your while-loop will automatically exit when interrupted.
Lastly, Object.wait is useless unless another thread calls Object.notify or Object.notifyAll on the very same object on which the waiting thread is synchronized. The wait method will (probably) never return unless the object gets a notify:
public void pauseThread() {
synchronized (lock) {
shouldThreadRun = false;
// Tell waiting thread that shouldThreadRun may have changed.
lock.notify();
}
}
public void resumeThread() {
synchronized (lock) {
shouldThreadRun = true;
// Tell waiting thread that shouldThreadRun may have changed.
lock.notify();
}
}
Notice that the synchronizing is inside the methods. If you keep your thread synchronized on lock all the time, the manager thread will never have a chance to run at all, because it’s trying to acquire a synchronization lock on the same object. (However, the opposite is not true; the manager thread can stay synchronized on lock all the time, because the wait() method will temporarily release the synchronization lock, allowing the other thread to proceed.)
If all code which accesses shouldThreadRun is inside synchronized blocks, you don’t need to (and should not) make shouldThreadRun volatile, since the synchronization already ensures multi-threaded consistency.

Threads notifyAll() [duplicate]

This question already has answers here:
Java: notify() vs. notifyAll() all over again
(26 answers)
Closed 4 years ago.
Given a thread has multiple states: alive runnable running waiting and terminated.
the notifyAll() method is suppose to put all threads that are "waiting" on an object's lock back into the "runnable" state where it is may be chosen as the next running object.
The following example instantiates and starts 3 Reader threads, which go into waiting (wait() method) until the 'calc' object's lock is released. The calc objects thread is instantiated and started just after this where it adds up some numbers, followed by notifyAll().
My question is, why doesn't the calc thread notify all the Reader threads every time? when I run this on my computer it's hit and miss.
public class Reader extends Thread{
Calculator c;
public Reader(Calculator calc){
c=calc;
}
public void run(){
synchronized(c){
try{
System.out.println("Waiting for calculation...");
c.wait();
}catch(InterruptedException e){}
System.out.println("Total is: "+c.total);
}
}
public static void main(String[] args){
Calculator calc = new Calculator();
new Reader(calc).start();
new Reader(calc).start();
new Reader(calc).start();
new Thread(calc).start();
}
}
class Calculator implements Runnable{
int total;
public void run(){
synchronized(this){
for(int i =0; i<100; i++){
total+=i;
}
notifyAll();
}
}
}
When executing multiple threads, order of execution of the threads is not guaranteed.
In your case chances are that the Calculator thread completes it's loop and calls notifyAll() even before any of the Reader threads gets into runnable state. So all Reader will keep waiting and will never print total.
To avoid such situation, in this particular example you can use another flag isCalculated in Calculator and set this flag once computation is done. Reader threads will also check for this flag and wait only when isCalculated is false.
class Reader extends Thread {
Calculator c;
public Reader(Calculator calc) {
c = calc;
}
public void run() {
synchronized (c) {
try {
System.out.println("Waiting for calculation...");
if (!c.isCalculated) { // wait only if calculation is not done
c.wait();
}
} catch (InterruptedException e) {
}
System.out.println("Total is: " + c.total);
}
}
}
class Calculator implements Runnable {
int total;
boolean isCalculated;
public void run() {
synchronized (this) {
for (int i = 0; i < 100; i++) {
total += i;
}
isCalculated = true; // set flag to mark that computation is complete
notifyAll();
}
}
}
As mentioned by #Sudhir you can check some flags before calling wait ,
check this tutorial: http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
In your case notifyAll() may be called before wait is called .. so the threads may keep on waiting for the notify to be called

Last thread is not executing

I am very new to multithreading, was trying a scenario in which a home has a mother(as producer),son,daughter and husband[As consumer] thread.I am trying to understand how wait and notify method can help here.
My classes are as below.
MotherAsProducer
package com.test.All.Threads;
public enum MotherAsProducer {
INSTANCE;
/*
*
*
* son Give request to prepare chapati to mother
* mother accepts it and start preparing , son/husband/daughter should wait by that time.
* mother notifies son/daughtor/husband that chapati is ready start consuming
* */
public synchronized void takeOrderAndMakeChapati(){
try {
System.out.println("Request got from "+Thread.currentThread().getName());
getStatusOfChapati();
wait();
System.out.println(Thread.currentThread().getName()+" ate chapati");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//lock re-entrance
public synchronized void getStatusOfChapati(){
try {
Thread.sleep(1200);
System.out.println("Chapati is prepared for "+Thread.currentThread().getName());
notifyAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static MotherAsProducer getMotherInstance(){
return MotherAsProducer.INSTANCE;
}
}
SonAsConsumer class
package com.test.All.Threads;
public class SonAsConsumer implements Runnable{
public void run(){
MotherAsProducer.getMotherInstance().takeOrderAndMakeChapati();
}
}
DaughterAsConsumer class
package com.test.All.Threads;
public class DaughterAsConsumer implements Runnable {
public void run(){
MotherAsProducer.getMotherInstance().takeOrderAndMakeChapati();
}
}
HusbandAsConsumer class
package com.test.All.Threads;
public class HusbandAsConsumer implements Runnable {
public void run(){
MotherAsProducer.getMotherInstance().takeOrderAndMakeChapati();
}
}
Home class
package com.test.All.Threads;
public class Home {
public static void main(String args[]){
SonAsConsumer sac = new SonAsConsumer();
DaughterAsConsumer dac = new DaughterAsConsumer();
HusbandAsConsumer hac = new HusbandAsConsumer();
Thread tsac = new Thread(sac);
tsac.setName("Son");
Thread tdac = new Thread(dac);
tdac.setName("Daughter");
Thread thac = new Thread(hac);
thac.setName("Husband");
tsac.start();
tdac.start();
thac.start();
}
}
My output is different, every time as expected by nature of thread but one of the individual either husband, daughtor or son is not getting complete.
one instance of my output is as below.
Order she got from Daughter
Chapati is prepared for Daughter
Order she got from Son
Chapati is prepared for Son
Order she got from Husband
Chapati is prepared for Husband
Son ate chapati
Daughter ate chapati
My understanding here is when son,daughter and husband will start executing one of them will hit the synchronized method and execute wait() and will hold the lock , from that synchronized method again another synchronized method is called which will contain notify and the lock will be released and another thread will try to get the lock from the blocked pool and will execute in the same manner . here two threads are behaving as expected but the last one is not.
Kindly help here.
Briefly looking, it looks like the last thread to get to the wait will never get notified. Sequencing your calls you have each thread getting a lock, notifying all waiting threads, and then waiting. So, the last thread that hits the wait will never have anyone to notify them that they need to exit.
That is, if Thread A gets the lock initially, then it will do a println and a sleep then a println, then notify all waiting threads (there are none), and then become a waiting thread.
Then, lets say Thread B gets the lock. It will do a println and a sleep, then it will notify all (which will "notify" Thread A), then it will wait.
Now, either Thread C or Thread A will get the lock. If Thread A gets it, it will simply fall through and complete with the "ate" message. Then, Thread C can get the lock and it will eventually notify, waking B which can eat once C "waits". Now, there is no thread left to notify so that C will complete.
This make sense? Did I misread anything?
To verify what I'm suggesting is wrong, simply add in more threads. You should always have the last one that prints "Chapati is prepared for ..." will never eat it.
Fundamentally, I think the confusion is that "Mother" is not actually doing any work. What you probably wanted is to have "Mother" be a thread that has its own work log. So, when one of the other threads gives her work, you set a variable then notify mother and wait as the sibling. The mother will then wake up and do the work and notify the current thread waiting.
See what I mean? Metaphorically, you have 4 people in this program. But, you only have 3 threads.
Change the method in the enum class MotherAsProducer as follows: The unnecessary wait() method caused the issue. Since the method is synchronized, all other threads will be blocked before entering into the method until getting a notification from lock holding thread.
public synchronized void takeOrderAndMakeChapati() {
System.out.println("Request got from " + Thread.currentThread().getName());
getStatusOfChapati();
// wait(); - THIS WAIT IS CAUSING THE PROBLEM
System.out.println(Thread.currentThread().getName() + " ate chapati");
}
Remove wait and notifyAll calls from both takeOrderAndMakeChapati and getStatusOfChapati. You will get the expected result.
As precisely mentioned by Josh, one of the threads (last one) is still waiting for some external notification, and there is nobody to notify. You code is still running in the background. Just call wait(5000) and you can see it happening.
Both methods takeOrderAndMakeChapati and getStatusOfChapati are synchronized, therefore synchronization is not the issue.
Generally threads wait for some external dependency or condition, where some other thread(s) notifies the waiting one, when that condition is fulfilled.
I also tried to understand wait and notify when I started with multithreading. But as soon as I learned to use a Semaphore, I never looked back. Hopefully, the example below will give you some insight into the benefits of using a Semaphore. There is also a lot more useful stuff in the java.util.concurrent package that can be of great help.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class EatChapati {
static int CHAPATI_PREPARE_TIME_MS = 100;
static long RUN_TIME_MS = 2000;
static long SHUTDOWN_TIME_MS = 500;
static int CHAPATI_CONSUMERS = 5;
static volatile boolean stop;
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < CHAPATI_CONSUMERS; i++) {
executor.execute(new ChapatiConsumer(i + 1));
}
try { Thread.sleep(RUN_TIME_MS); } catch (Exception ignored) {}
stop = true;
executor.shutdownNow();
try { executor.awaitTermination(SHUTDOWN_TIME_MS, TimeUnit.MILLISECONDS); } catch (Exception ignored) {}
}
// 1 producer making chapati's
// 'true' for a fair semaphore: longest waiting consumer gets served
static Semaphore chapatiTurn = new Semaphore(1, true);
static AtomicInteger chapatiCount = new AtomicInteger();
static int getChapati(int consumerNumber) {
int chapatiNumber = 0;
boolean haveTurn = false;
try {
chapatiTurn.acquire();
// start of 'synchronized' block
haveTurn = true;
Thread.sleep(CHAPATI_PREPARE_TIME_MS);
chapatiNumber = chapatiCount.incrementAndGet();
System.out.println("Chapati " + chapatiNumber + " prepared for consumer " + consumerNumber);
} catch (Exception e) {
// Triggered by executor.shutdownNow
stop = true;
} finally {
if (haveTurn) {
chapatiTurn.release();
// end of 'synchronized' block
}
}
return chapatiNumber;
}
static class ChapatiConsumer implements Runnable {
int number;
ChapatiConsumer(int number) {
this.number = number;
}
public void run() {
int chapatisConsumed = 0;
while (!stop) {
if (getChapati(number) > 0) {
chapatisConsumed++;
}
}
System.out.println("Consumer " + number + " stopped after consuming " + chapatisConsumed + " chapatis.");
}
}
}

Why doesn't thread wait for notify()?

Why doesn't thread wait for notify()? The thread starts and then goes to the waiting pool, but it proceeds to execute after that moment.
public class JavaApplication2 {
public static void main(String [] args) {
ThreadB b = new ThreadB();
synchronized(b) {
b.start();
try {
System.out.println("1");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
synchronized(this) {
total += 1;
//notify();
}
}
}
You are synchronizing on the thread object itself, which is wrong usage. What happens is that the dying thread-of-execution always calls notify on its Thread object: Thread.join relies on this. Therefore it is clear why you get the same behavior with and without your own notify in there.
Solution: use a separate object for thread coordination; this is the standard practice.
The method notifyAll() is invoked for the Thread object of the terminating thread. This fact is strangely documented in the description of the Thread.join, with the following sentence:
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Thus, if you don't explicitly read the description of join, which you don't necessarily have to, you don't get to know the reason for the strange behavior.
You cannot depend on not returning from wait until a notify: "interrupts and spurious wakeups are possible". In general, you should wrap a wait call in a loop while the thread should go on waiting.
If you try your code synchronizing on any object other that ThreadB you will find it never terminates. This is because there is a hidden call to notify.
Although I am not aware of anywhere that this is specified, Thread notifies itself when it ends. This is implicit in the way the join method is implemented. This is the code for join:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
(From the JDK7 source code)
As you can see, the calls to wait only make sense if somewhere there is a call to notify that is called after the thread ends. The same call to notify is what allows your program to terminate.
You have nested synchronized {} constructs in the two places. These constructs seem doing something weird: the thread does not react into notify at all and only resumes when ThreadB (b) terminates. Remove this:
public class JavaApplication2 {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
try {
System.out.println(" ### Waiting for notify");
synchronized (b) {
b.wait();
}
System.out.println(" ### Notified");
} catch (InterruptedException e) {
}
System.out.println("### Total is: " + b.total);
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
total += 1;
System.out.println(" *** Ready to notify in 5 secs");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** Notification sent");
synchronized (this) {
notify();
}
System.out.println(" *** 5 sec post notification");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** ThreadB exits");
}
}
The code above probably works correctly: with notify() present the main thread resumes after 5 seconds and before we see the message that ThreadB terminates. With notify() commented out the main thread resumes after 10 seconds and after the message about the termination of the ThreadB because notify() is called anywhay from the other code. Marko Topolnik explains why and from where this "behind the scene" notify() call comes from.
I was doing the same testing on the wait/notify opertaions while reading OCP SE 7, good catch. I think we should let the authoer to explain.

Categories