I have following Thread example:
class TickTock {
String state; // contains the state of the clock
synchronized void tick(boolean running) {
if(!running) { // stop the clock
state = "ticked";
notify(); // notify any waiting threads
return;
}
System.out.print("Tick ");
state = "ticked"; // set the current state to ticked
notify(); // let tock() run
try {
while(!state.equals("tocked"))
wait(); // wait for tock() to complete
}
catch(InterruptedException exc) {
System.out.println("Thread interrupted.");
}
}
synchronized void tock(boolean running) {
if(!running) { // stop the clock
state = "tocked";
notify(); // notify any waiting threads
return;
}
System.out.println("Tock");
state = "tocked"; // set the current state to tocked
notify(); // let tick() run
try {
while(!state.equals("ticked"))
wait(); // wait for tick to complete
}
catch(InterruptedException exc) {
System.out.println("Thread interrupted.");
}
}
}
class MyThread implements Runnable {
Thread thrd;
TickTock ttOb;
// Construct a new thread.
MyThread(String name, TickTock tt) {
thrd = new Thread(this, name);
ttOb = tt;
thrd.start(); // start the thread
}
// Begin execution of new thread.
public void run() {
if(thrd.getName().compareTo("Tick") == 0) {
for(int i=0; i<5; i++) ttOb.tick(true);
ttOb.tick(false);
}
else {
for(int i=0; i<5; i++) ttOb.tock(true);
ttOb.tock(false);
}
}
}
class ThreadCom {
public static void main(String args[]) {
TickTock tt = new TickTock();
MyThread mt1 = new MyThread("Tick", tt);
MyThread mt2 = new MyThread("Tock", tt);
try {
mt1.thrd.join();
mt2.thrd.join();
} catch(InterruptedException exc) {
System.out.println("Main thread interrupted.");
}
}
}
How it comes that mt2 is waiting for mt1? Is that because mt1 is created before mt2 and therefore enters the synchronized method first? If yes - next question is: Why mt1 calls notify() before wait()? How can be the monitor released without calling wait()?
I understand it this way: mt1: I can not do any more work here so I will wait() and then I notify() mt2.
Now when I am writing this I realized that maybe thread that calls wait() can no longer call any other methods? So maybe that is why notify() needs to be called first?
Can someone please explain it to me? Thank you!
How it comes that mt2 is waiting for mt1?
After mt2 sets the state to "tocked", it waits until it gets changed to "ticked". Only mt1 can do that.
Is that because mt1 is created before mt2 and therefore enters the synchronized method first?
It doesn't matter which thread enters the method first. Each one waits for the other if necessary. If the thread that can make forward progress gets the lock first, it makes forward progress. If the wrong thread gets the lock, it just waits for the other, releasing the lock and allowing that thread to make forward progress.
If yes - next question is: Why mt1 calls notify() before wait()?
Since mt has changed the state and another thread might be waiting for the state to change, it's important to call notify. Calling wait first would be a disaster -- the other thread might be waiting to get notified about the change this thread made and two threads waiting for each other is a deadlock.
How can be the monitor released without calling wait()?
It can't be. But it doesn't matter. The thread will release the monitor either when it is entirely finished or when it's waiting for the other thread. In all other cases, it's actively modifying shared states and you don't want the lock released.
Related
This program works fine by printing alternate numbers via different threads but when all the numbers from 0-9 are printed Why does this program not stop? I have to manually stop my application.
public class EvenOddPrinter implements Runnable{
private AtomicInteger num = new AtomicInteger(0);
private Object lock = new Object();
#Override
public void run() {
synchronized (lock){
while (num.get()<10){
System.out.println(num.getAndAdd(1) + " - "+Thread.currentThread().getName());
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Executor {
public static void main(String[] args) throws InterruptedException {
EvenOddPrinter eop = new EvenOddPrinter();
Thread t1 = new Thread(eop);
Thread t2 = new Thread(eop);
t1.start();
t2.start();
}
}
that's because in the last Thread getting stuck at wait. notifyAll will notify all waiting thread if any there and release lock.
while (num.get()<10){
// existing implementation
}
lock.notifyAll();
The second thread t2 keeps waiting on the lock in the end, and t1 doesnt do the notify() anymore because the while condition becomes false. You must put a lock.notify(); statement outside of the while loop.
As soon as the number reached 8 the first thread calls notify() and goes to wait(). Second thread then makes the number 9 and calls notify() and goes to wait(). First thread is then not able to go inside the loop as specified in the condition, therefore, it exits the synchronized and block and finishes but second thread is still waiting. There has to be a mechanism to notifyAll() as soon as one of the threads exits the synchronized block which is exactly what I did.
#Override
public void run() {
synchronized (lock){
while (num.get()<10){
System.out.println(num.getAndAdd(1) + " - "+Thread.currentThread().getName());
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notifyAll();
}
Also, lock is pointless when I am using AtomicInteger (or the other way round).
I am trying to implement a blocking queue(only on consumer side) with ReentrantLock and conditions but am running into a state where the JVM doesn't terminate. The strange thing is that one thread gets interrupted but the other doesn't. I am sure I am making some mistake but just can't figure out what.
EDIT:
Main Question: Why does only one thread throw an interruptedexception when both the threads are blocking on condition.await
So the code below is just an example that i created. The main problem was to develop a producer-consumer implementation in which I had to create a simulation class which spawned two kinds of threads, customers and cooks, which were synchronized based on a Reentrant lock. After some operations were performed(customers adding orders and cooks performing serving those orders),I call join on customer threads to make sure that all orders have been processed and then to stop the cook threads, I called interrupt on the cook threads to terminate them. But only one thread throws interruptedexception and the second one doesn't. Why is that? since both the threads are blocking on await.
My code is as follows:
Thread class:
public class InterruptedThread implements Runnable{
private final Lock lock;
private final Condition condition;
private final Queue<Integer> orderQueue;
public InterruptedThread(Lock lock, Condition condition,Queue<Integer> orderQueue)
{
this.lock = lock;
this.condition = condition;
this.orderQueue = orderQueue;
}
#Override
public void run() {
try{
while(true)
{
this.lock.lockInterruptibly();
while(orderQueue.size() == 0 && !Thread.currentThread().isInterrupted())
{
System.out.println("Inside blocking wait" + Thread.currentThread().getName());
condition.await();
}
int i = orderQueue.poll().intValue();
System.out.println("Value read:" + i + "by thread" + Thread.currentThread().getName());
this.lock.unlock();
}
}
catch(InterruptedException ex)
{
System.out.println("Interrupted exception" + Thread.currentThread().getName());
this.condition.signalAll();
Thread.currentThread().interrupt();
}
}
}
Main class:
public class ExplicitLockCondition {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Queue<Integer> orderQueue = new LinkedList<>();
Lock lock = new ReentrantLock();
Condition testCondition = lock.newCondition();
Thread[] ths = new Thread[2];
for(int i=0; i<ths.length;i++)
{
ths[i] = new Thread(new InterruptedThread(lock, testCondition,orderQueue));
ths[i].start();
}
lock.lock();
orderQueue.add(1);
lock.unlock();
lock.lock();
orderQueue.add(2);
lock.unlock();
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(ExplicitLockCondition.class.getName()).log(Level.SEVERE, null, ex);
}
lock.lock();
orderQueue.add(-99);
lock.unlock();
for(int i=0; i<ths.length;i++)
{
ths[i].interrupt();
}
System.out.println("After loop exited!!!");
for(int i=0; i<ths.length;i++)
{
System.out.println("Interrupted thread:" + ths[i].getName() +"with interrupt flag:" + ths[0].isInterrupted());
}
for(int i=0; i<ths.length;i++)
{
try {
ths[i].join();
} catch (InterruptedException ex) {
Logger.getLogger(ExplicitLockCondition.class.getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("Program exited!!!");
}
}
You have
condition.await();
but the only place you signal it is in the catch block.
In a typical run of your application, your InterruptedThread (let's call it it1) will enter the while loop and await on the condition, putting itself in a waiting state. Your main thread will do a bunch of things and eventually interrupt it1. You'll note the javadoc of Condition#await() states
In all cases, before this method can return the current thread must
re-acquire the lock associated with this condition.
So thread it2 reacquires the lock and because it's been interrupted
If the current thread:
has its interrupted status set on entry to this method; or
is interrupted while waiting and interruption of thread suspension is supported,
then InterruptedException is thrown and the current thread's
interrupted status is cleared.
So execution leaves the while block and goes to the catch. During this time, your thread it2 still owns the lock, since nothing unlocked it. The catch block then calls
this.condition.signalAll();
which signals the condition. Thread it1 then completes normally. However, the Lock is still locked and nothing can acquire it which is why your other InterruptedThread cannot continue from within its
condition.await();
You basically have to manage locking and unlocking your Lock better.
a) you never signal the condition after you insert a value to your queue
b) your thread will leave
while(orderQueue.size() == 0 && !Thread.currentThread().isInterrupted())
if it is interrupted, and then tried to poll the value from the queue.
If there is no value there, the null will be returned and you end up with uncaught null pointer exception but the lock will never be unlock.
Allways
lock.lock()l
try {
...
} finally {
lovk.unlovk();
}
I don't see how the following code produces output that appears to contravene the definition of an object lock. Surely only one thread should be allowed to print the "acquired lock" message yet they both do?
class InterruptThreadGroup {
public static void main(String[] args) {
Object lock = new Object();
MyThread mt1 = new MyThread(lock);
MyThread mt2 = new MyThread(lock);
mt1.setName("A");
mt1.start();
mt2.setName("B");
mt2.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
// Thread.currentThread().getThreadGroup().interrupt();
}
}
class MyThread extends Thread {
private Object lock;
public MyThread(Object l) {
this.lock = l;
}
public void run() {
synchronized (lock) {
System.out.println(getName() + " acquired lock");
try {
lock.wait();
} catch (InterruptedException e) {
System.out.println(getName() + " interrupted.");
}
System.out.println(getName() + " terminating.");
}
}
}
It is because the call to lock.wait() releases the lock, allowing the second thread to enter the synchronized block. Extract from the javadoc
The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
Note that there are a few issues in your code such as:
you should not wait outside of a while loop
there is no notify anywhere so your wait could last forever
it is a better practice to have your task implement Runnable and pass it as an argument to a Thread's constructor than to extend Thread directly.
Either you should use synchronized block or wait call . using them together will not work. if you use wait call then the lock is released by the object in synchronized block.
So remove the line lock.wait and your programme will work as you want. synchronize block will handle all lock automatically.
if you are using wait then must use notify.
Here is good thread about this: Why must wait() always be in synchronized block
I'm trying to understand how threads work, and I wrote a simple example where I want to create and start a new thread, the thread, display the numbers from 1 to 1000 in the main thread, resume the secondary thread, and display the numbers from 1 to 1000 in the secondary thread. When I leave out the Thread.wait()/Thread.notify() it behaves as expected, both threads display a few numbers at a time. When I add those functions in, for some reason the main thread's numbers are printed second instead of first. What am I doing wrong?
public class Main {
public class ExampleThread extends Thread {
public ExampleThread() {
System.out.println("ExampleThread's name is: " + this.getName());
}
#Override
public void run() {
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
}
}
public static void main(String[] args) {
new Main().go();
}
public void go() {
Thread t = new ExampleThread();
t.start();
synchronized(t) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
synchronized(t) {
t.notify();
}
}
}
You misunderstand how wait/notify works. wait does not block the thread on which it is called; it blocks the current thread until notify is called on the same object (so if you have threads A and B and, while in thread A, called B.wait(), this will stop thread A and not thread B - for as long as B.notify() is not called).
So, in your specific example, if you want main thread to execute first, you need to put wait() inside the secondary thread. Like this:
public class Main {
public class ExampleThread extends Thread {
public ExampleThread() {
System.out.println("ExampleThread's name is: " + this.getName());
}
#Override
public void run() {
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
}
}
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
}
}
public static void main(String[] args) {
new Main().go();
}
public void go() {
Thread t = new ExampleThread();
t.start();
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
synchronized(t) {
t.notify();
}
}
}
However, even this code may not work like you want. In a scenario where the main thread gets to the notify() part before the secondary thread had a chance to get to the wait() part (unlikely in your case, but still possible - you can observe it if you put Thread.sleep at the beginning of the secondary thread), the secondary thread will never be waken up. Therefore, the safest method would be something similar to this:
public class Main {
public class ExampleThread extends Thread {
public ExampleThread() {
System.out.println("ExampleThread's name is: " + this.getName());
}
#Override
public void run() {
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
}
}
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
}
}
public static void main(String[] args) {
new Main().go();
}
public void go() {
Thread t = new ExampleThread();
synchronized (t) {
t.start();
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
synchronized(t) {
t.notify();
}
}
}
In this example the output is completely deterministic. Here's what happens:
Main thread creates a new t object.
Main thread gets a lock on the t monitor.
Main thread starts the t thread.
(these can happen in any order)
Secondary thread starts, but since main thread still owns the t monitor, the secondary thread cannot proceed and must wait (because its first statement is synchronized (this), not because it happens to be the t object - all the locks, notifies and waits could as well be done on an object completely unrelated to any of the 2 threads with the same result.
Primary thread continues, gets to the t.wait() part and suspends its execution, releasing the t monitor that it synchronized on.
Secondary thread gains ownership of t monitor.
Secondary thread calls t.notify(), waking the main thread. The main thread cannot continue just yet though, since the secondary thread still holds ownership of the t monitor.
Secondary thread calls t.wait(), suspends its execution and releases the t monitor.
Primary thread can finally continue, since the t monitor is now available.
Primary thread gains ownership of the t monitor but releases it right away.
Primary thread does its number counting thing.
Primary thread again gains ownership of the t monitor.
Primary thread calls t.notify(), waking the secondary thread. The secondary thread cannot continue just yet, because the primary thread still holds the t monitor.
Primary thread releases the t monitor and terminates.
Secondary thread gains ownership of the t monitor, but releases it right away.
Secondary thread does its number counting thing and then terminates.
The entire application terminates.
As you can see, even in such a deceptively simple scenario there is a lot going on.
You are lucky that your program terminates at all.
When you call t.wait() your main threads stops and waits indefinitely on a notification.
It never gets it, but I believe is awaken by spurious wakeup when the secondary thread finishes. (Read here on what a spurious wakeup is).
ExampleThread doesn't wait() or notify(), and isn't synchronized on anything. So it will run whenever it can without any coordination with other threads.
The main thread is waiting for a notification which never comes (this notification should be sent by another thread). My guess is that when the ExampleThread dies, the main thread is woken "spuriously," and completes.
The thread that should wait for another to complete must perform the call to wait() inside a loop that checks for a condition:
class ExampleThread extends Thread {
private boolean ready = false;
synchronized void ready() {
ready = true;
notifyAll();
}
#Override
public void run() {
/* Wait to for readiness to be signaled. */
synchronized (this) {
while (!ready)
try {
wait();
} catch(InterruptedException ex) {
ex.printStackTrace();
return; /* Interruption means abort. */
}
}
/* Now do your work. */
...
Then in your main thread:
ExampleThread t = new ExampleThread();
t.start();
/* Do your work. */
...
/* Then signal the other thread. */
t.ready();
I've got the following code, which I expected to deadlock after printing out "Main: pre-sync". But it looks like synchronized doesn't do what I expect it to. What happens here?
import java.util.*;
public class deadtest {
public static class waiter implements Runnable {
Object obj;
public waiter(Object obj) {
this.obj = obj;
}
public void run() {
System.err.println("Thead: pre-sync");
synchronized(obj) {
System.err.println("Thead: pre-wait");
try {
obj.wait();
} catch (Exception e) {
}
System.err.println("Thead: post-wait");
}
System.err.println("Thead: post-sync");
}
}
public static void main(String args[]) {
Object obj = new Object();
System.err.println("Main: pre-spawn");
Thread waiterThread = new Thread(new waiter(obj));
waiterThread.start();
try {
Thread.sleep(1000);
} catch (Exception e) {
}
System.err.println("Main: pre-sync");
synchronized(obj) {
System.err.println("Main: pre-notify");
obj.notify();
System.err.println("Main: post-notify");
}
System.err.println("Main: post-sync");
try {
waiterThread.join();
} catch (Exception e) {
}
}
}
Since both threads synchronize on the created object, I expected the threads to actually block each other. Currently, the code happily notifies the other thread, joins and exits.
Calling .wait() on a monitor actually releases the synchronized lock so the other thread can lock on to the same monitor and send a notification.
Your behavior is completly normal: "waiter" locks on a monitor and then releases the lock when waiting for notification. After 1 second the main thread locks the monitor, sends notification, unlocks the monitor, which wakes the waiter to complete its operation.
When you wait() on an object, the thread releases the lock on the object to allow others to aquire the lock and notify() the waiting thread. See the javadoc for Object.wait().
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.