I've this class:
public class MyThread implements Runnable {
private static boolean canAccess = true;
private Thread t;
public FirstThread(String name) {
t = new Thread(this);
t.setName(name);
}
public void start() {
t.start();
}
private synchronized void accessed(String name) throws InterruptedException {
if (canAccess) {
canAccess = false;
System.out.println("Accessed " + name);
try {
Thread.sleep(5000);
} catch (Exception e) {
}
canAccess = true;
System.out.println("NOTIFY: " + name);
notifyAll();
}
System.out.println("WAIT: " + name);
wait();
}
#Override
public void run() {
while (true) {
try {
accessed(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
And this is my output:
Accessed 1
WAIT: 3
WAIT: 5
WAIT: 7
WAIT: 9
WAIT: 0
WAIT: 2
WAIT: 4
WAIT: 6
WAIT: 8
NOTIFY: 1
WAIT: 1
and my app freeze (deadlock state).
Seems that the notifyAll method doesn't work. Where is my error?
My Main class.
public class Main {
public static void main(String[] args) {
MyThread [] threads = new MyThread[10];
for(int i=0;i<threads.length;i++) {
threads[i] = new MyThread(""+i);
threads[i].start();
}
}
}
wait means that the thread releases the lock and goes into a dormant state until another thread notifies it. notifyAll means that the thread tells all the other threads waiting on the lock being used in the current synchronized block to wake up and try to acquire the lock again. Your code example doesn't have any cases where multiple threads are trying to acquire the same lock so using wait and notifyAll here doesn't make any sense. There's nothing to wake up the thread once it calls wait.
One typical use of wait and notify: You might have many producers putting stuff in a queue, and consumer threads that take stuff out of the queue. The queue has a take method that the consumer calls, if the queue is empty then it calls wait and the consumer blocks. The queue has a put method that calls notifyAll when something goes into the queue so that any waiting consumer threads wake up.
There's a producer-consumer example of using wait and notifyAll in the Java tutorial.
Every Thread waits on it's own instance, that's why they all are stuck in one place.
If you had a private static Object LOCK = new Object(); and call LOCK.wait(); and LOCK.notify(); this could be another story.
I have also doubts about synchronized modifier for accessed() method. It's just doesn't have use in the described situation. I would better modify the "canAccess" variable in synchronized block.
Related
I'm trying to resolve a university exercise. The class AImpl has a method ma(B b) that creates and runs two threads. These threads have to call mb1() and mb2() (they are simple methods that just print a text, so I didn't include them). The calling thread should then wait for mb1() to terminate before finishing.
My logic is:
The first thread enters and after finishing the execution of b.mb1() starts to wait() on the current object, releasing the mutex. Then the second thread runs and it does the same. When they are both waiting, the calling thread calls notifyAll() on the object, waking both of them. They execute b.mb2() and then terminate.
The problem is that when the first thread starts waiting with object.wait(), the control flow doesn't return on the calling thread and the program enters in a deadlock.
Where is my logic flawed?
public class AImpl{
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
BImpl b = new BImpl();
AImpl.ma(b);
}
public static void ma(B b) throws InterruptedException {
Thread thread = new Thread() {
#Override
public void run() {
b.mb1();
synchronized(object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
b.mb2();
System.out.println("Thread finished");
}
};
Thread thread1 = new Thread() {
#Override
public void run() {
b.mb1();
synchronized(object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
b.mb2();
System.out.println("Thread finished");
}
};
thread.run();
thread1.run();
synchronized(object){
object.notifyAll();
}
System.out.println("Program finished.");
}
}
The notify/notifyAll methods tell the scheduler to notify one/all of the threads currently waiting on the lock that notify or notifyAll was called on. But if a thread hasn't started waiting yet then it doesn't get notified.
The solution is to introduce a condition variable that keeps wait from being called if the notifying has happened already. Define it in the same scope as your lock:
public static volatile boolean ready = false;
Then use it to guard the wait block, like this:
while (!ready) {
object.wait();
}
The code calling notify/notifyAll needs to set the variable (it doesn't matter what order you do it in because the notification doesn't happen until the lock is released):
synchronized (object) {
ready = true;
object.notifyAll();
}
What happens:
If the waiting thread gets to the waiting part before the notifying thread does its notifying, then the waiting thread finds ready is false, so it enters the wait method, releases the lock, and stays there. Then the notifying thread changes the flag to true and wakes up the waiting thread, which can leave the wait, reacquire the lock, and then leave the loop now that the flag is set.
But if the notifying thread does its notify before the other thread waits, that's ok, because the ready flag now prevents the thread from entering the wait, it can skip over it.
Further reading: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
I have the following simple code in which I put and take from a Queue represented as an ArrayList.
public class EmailService {
private Queue<Email> emailQueue;
private Object lock;
private volatile boolean run;
private Thread thread;
public void sendNotificationEmail(Email email) throws InterruptedException {
emailQueue.add(email);
synchronized (lock) {
lock.notify();
lock.wait();
}
}
public EmailService() {
lock = new Object();
emailQueue = new Queue<>();
run = true;
thread = new Thread(new Runnable() {
#Override
public void run() {
while (run) {
System.out.println("ruuuning");
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (emailQueue.getSize() > 0) {
sendEmail(emailQueue.poll());
}
lock.notify();
}
}
}
private void sendEmail(Email email) {
System.out.println("Sent email from " + email.getFrom() + " to " + email.getTo() + " with content: " + email.getContent());
}
});
thread.start();
}
public void close() throws InterruptedException {
run = false;
synchronized (lock) {
lock.notify();
System.out.println("Thread will join " + thread.isInterrupted());
thread.join();
System.out.println("Thread after join");
}
}
}
I don't understand why my thread is blocked in join() method.
From main I call as follow:
eService = new EmailService();
Email e1 = new Email(client1, client2, "content1");
eService.sendNotificationEmail(e1);
eService.close();
Without running it...
The close() method holds lock at the time it calls thread.join() and waits on thread (forever)
thread is waiting to reacquire lock so cannot run
Both are now waiting on each other, this is a deadlock. Try moving the Thread.join() after the synchronized block:
public void close() throws InterruptedException {
run = false;
synchronized (lock) {
lock.notify();
System.out.println("Thread will join " + thread.isInterrupted());
}
thread.join();
System.out.println("Thread after join");
}
#drekbour explained how your program could hang in the join() call, but FYI: Here's a different way that your program could hang. This is called lost notification.
Your main thread creates a new EmailService instance. The new instance creates its thread and calls thread.start() *BUT* it could take some time for the thread to actually start running. Meanwhile...
Your main thread creates a new Email instance, and calls eService.sendNotificationEmail(...). That function adds the new message to the queue, locks the lock, notifies the lock, and then waits on the lock.
Finally, The service thread starts up, enters its run() method, locks the lock, and then it calls lock.wait().
At this point, the program will be stuck because each thread is waiting to be notified by the other.
The way to avoid lost notification is, in the consumer thread, do not call wait() if the thing that you are waiting for already has happened.
synchronized(lock) {
while (theThingHasNotHappenedYet()) {
lock.wait();
}
dealWithTheThing();
}
In the producer thread:
synchronized(lock) {
makeTheThingHappen();
lock.notify();
}
Notice how both threads lock the lock. Ever wonder why lock.wait() throws an exception if the lock isn't locked? The examples above illustrate why. The lock prevents the producer thread from making the thing happen after the consumer already has decided to wait. That is key: If the consumer were to wait after the producer calls notify() then it's game over. The program hangs.
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.
I've been trying to make a simple Java thread application, where one thread waits, and another wakes it up after 3 seconds. However, I can't seem to make it work and I just can't figure out why.
public class Deadlock extends Thread {
Object lock = new Object();
public static void main(String[] args) {
//WAITER THREAD
Deadlock waiter = new Deadlock() {
#Override
public void run() {
System.out.println("Waiter started");
synchronized(lock) {
try{
System.out.println("Waiter will wait for notify...");
lock.wait();
System.out.println("Woke up!");
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}//run()
};
//WAKER THREAD
Deadlock waker = new Deadlock() {
#Override
public void run() {
System.out.println("Waker started");
synchronized(lock) {
System.out.println("Waker sleeping for 3 seconds.");
try{
Thread.sleep(3000);
}catch(InterruptedException e) {}
System.out.println("Waker notifying...");
lock.notifyAll();
}
}//run
};
waiter.start();
waker.start();
}
}
The output I get is:
Waiter started
Waiter will wait for notify...
Waker started
Waker sleeping for 3 seconds.
Waker notifying...
...and keeps running forever. I expected the waiter thread to wake up and the program to terminate.
Thanks
Your main problem is that the 'lock' is a class instance property so the two Deadlock instances do not share the same 'lock'. Hence, calling notifyAll() in the waker has no effect on the waiter because it's waiting on a different object. The simplest solution is to make 'lock' static:
static Object lock = new Object();
... I'd also make it private and final for good measure.
The second issue is that by starting the two threads together you don't really guarantee that the waiter will run first - I'd add a short delay before starting the waker.
I am trying to understand how deadlocks are created. I've understood that by using two threads on two synchronized methods, a deadlock can be created.
Went through many examples from the net.
Can a deadlock be created with wait and notify?
Every time a thread is on wait, it will be notified. So how does this end up in a deadlock?
Illustration of an example will be helpful.
Deadlock is caused when two threads try to obtain the same, multiple locks in different order:
// T1
synchronized (A) {
synchronized (B) {
// ...
}
}
// T2
synchronized (B) {
synchronized (A) {
// ...
}
}
The only way to prevent deadlocks is to make sure that all threads obtain locks in the same order--either they all do A then B, or they all do B then A.
If you don't have multiple locks, then you don't have a deadlock. However, you can get thread starvation or other things that may look similar to deadlock.
Say thread 1 enters a synchronized block on method A and then waits. Thread 2 then attempts to enter the synchronized block on method A. Thread 1 is waiting for a notify, and thread 2 is waiting on the synchronized block. Everything is now waiting. Some other thread will have to notify the object on which thread 1 is waiting. This is just one scenario that can create a deadlock. There are all kinds of ways to do it.
A thread which is on wait will not be notified unless some code explicitly notifies it. Therefore the example you are looking for is absolutely trivial:
public static void main(String[] args) {
synchronized(String.class) {
String.class.wait();
}
}
and this hangs forever. Technically, though, it is not a deadlock, which requires two or more threads involved in a closed cycle where each thread waits for the next one to unblock it.
Something close to wait/notify deadlock:
public class Example
{
volatile boolean isNotified = false;
public synchronized void method1() {
try
{
isNotified = false;
while (!isNotified)
wait();
notifyAll();
System.out.println("Method 1");
} catch (InterruptedException e) {/*NOP*/}
}
public synchronized void method2() {
try {
isNotified = true;
while (isNotified)
wait();
notifyAll();
System.out.println("Method 2");
} catch (InterruptedException e) {/*NOP*/}
}
public static void main(String[] args)
{
Example example = new Example();
Thread thread1 = new Thread()
{
public void run()
{
example.method1();
}
};
Thread thread2 = new Thread()
{
public void run()
{
example.method2();
}
};
thread1.start();
thread2.start();
}
}