Notify not getting the thread out of wait state - java

I am trying to use 2 threads. 1 thread prints only odd number and the other thread prints only even number and It has to be an alternative operation.
Eg:
Thread1 1
Thread2 2
Thread1 3
Thread2 4
and so on..
Below is the program, please let me know where I am going wrong as the thread1 is not coming out of wait state even when the thread2 is notifying it..
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (t) {
try {
t.notify();
t.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}

Problem is that in one case you are taking lock on Thread t [synchronized (t) ] while in other case you are taking lock on TheadA object itself [synchronized(this)].
If you want threads to talk to each other then both should take lock on same object only then wait notify will work as you expect.
Edit:
There is another problem in your program, you are not using any variable to coordinate between 2 threads. SO you may see output like this 2,1,4,3...so on. Point is threads will work alternately but not in sequence.
So you should share a single variable between 2 threads which should be incremented.
Second issue is you are not taking care of spurious wake up calls [read some docs on this], you should always have wait called inside a while loop.

Modified my code based on the answer provided by Lokesh
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (ta) {
try {
ta.notify();
ta.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}

You have a real confusion of threads and locks. I suggest you create one and only one object to use for locking to start with as you don't appear to have a clear idea what you are locking.
If you notify() and nothing is listening, the signal is lost. However, a wait() can wake spuriously.
For this reason, a notify() should be accompanied by a state change and a wait() should be in a loop checking that change.

Related

Unexpected behaviour of Threads

I am trying to achieve that thread2 should complete first, then thread1, For this O am using join() method. But if I uncomment the System.out.println() present in the try block of thread1 class. then
code give null pointer exception. Why in try block I need to add line, it doesn't make any sense that adding a line code start working.
Demo class
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
Thread1 class
public class Thread1 extends Thread {
#Override
public void run() {
try {
// System.out.println(); // on adding anyline, this whole code works!!, uncommenting this line of code give NPE
Thread2.fetcher.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thread2 class
public class Thread2 extends Thread {
static Thread fetcher;
#Override
public void run() {
fetcher= Thread.currentThread(); // got the thread2
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
OUTPUT of the program
in thread2 class Thread-2
Exception in thread "Thread-0" java.lang.NullPointerException
at org.tryout.Thread1.run(Thread1.java:22)
in thread2 class Thread-2
in thread2 class Thread-2
in thread2 class Thread-2
in thread2 class Thread-2
It is working purely by "pure luck" the
System.out.println();
internally calls synchronized, which is working as a delay that gives enough time for Thread 2 its field fetcher in:
fetcher= Thread.currentThread(); // got the thread2
In order to avoid this race-condition you need to ensure that the Thread 2 sets the field fetcher before Thread 1 accesses it. For that you case use, among others, a CyclicBarrier.
??A synchronization aid that allows a set of threads to all wait for
each other to reach a common barrier point.** CyclicBarriers are useful
in programs involving a fixed sized party of threads that must
occasionally wait for each other. The barrier is called cyclic because
it can be re-used after the waiting threads are released.
First, create a barrier for the number of threads that will be calling it, namely 2 threads:
CyclicBarrier barrier = new CyclicBarrier(2);
With the CyclicBarrier you can then force Thread 1 to wait for Thread 2 before accessing its field fetcher:
try {
barrier.await(); // Let us wait for Thread 2.
Thread2.fetcher.join();
} catch (InterruptedException | BrokenBarrierException e) {
// Do something
}
Thread 2 also calls the barrier after having setting up the field fetcher, accordingly:
fetcher = Thread.currentThread(); // got the thread2
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
Both threads will continue their work as soon as both have called the barrier.
An example:
public class Demo {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(2);
Thread1 t1 = new Thread1(barrier);
Thread2 t2 = new Thread2(barrier);
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
public class Thread1 extends Thread {
final CyclicBarrier barrier;
public Thread1(CyclicBarrier barrier){
this.barrier = barrier;
}
#Override
public void run() {
try {
barrier.await();
Thread2.fetcher.join();
} catch (InterruptedException | BrokenBarrierException e) {
// Do something
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread2 extends Thread {
static Thread fetcher;
final CyclicBarrier barrier;
public Thread2(CyclicBarrier barrier){
this.barrier = barrier;
}
#Override
public void run() {
fetcher = Thread.currentThread(); // got the thread2
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
If your code is not for education purposes, and you are not force to use any particular synchronization mechanism for learning purposes. In the current context you can simply pass the thread 2 as parameter of the thread 1, and call join directly on it as follows:
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1(t2);
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
public class Thread1 extends Thread {
final Thread thread2;
public Thread1(Thread thread2){
this.thread2 = thread2;
}
#Override
public void run() {
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread2 extends Thread {
#Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This should allow your code to work properly. There is insufficient time between thread startups to allow fletcher to initialize.
try {
Thread.sleep(500);
Thread2.fetcher.join();
} catch (InterruptedException ie) {
}
For something this simple, the sleep should work. But for more complicated threads, appropriate synchronization is the key. And you should be aware that thread programming can be one of the most difficult aspects of programming to debug.

What is wrong with my implementation of printing even odd numbers upto 10 using 2 threads

I am trying to print even and odd numbers using two different threads. Can some one point out the mistake I am making.
Currently this is what the output looks like:
Odd: 1
going to wait 1
notify 2
going to wait 2
Please find the code below:
public class EvenOdd {
public static void main(String[] args) {
PrintEvenOdd p1=new PrintEvenOdd(false);
PrintEvenOdd p2=new PrintEvenOdd(true);
p1.start();
p2.start();
}
}
class PrintEvenOdd extends Thread{
boolean isEven;
boolean isOdd=true;
public PrintEvenOdd(boolean e) {
isEven=e;
}
public synchronized void run() {
if(isEven) {
for(int i=2;i<=10;i+=2)
{
while(isOdd) {
try {
System.out.println("going to wait 1");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Even: "+i);
isOdd=true;
System.out.println("notify 1");
notifyAll();
}
}
if(!isEven) {
for(int i=1;i<=10;i+=2) {
while(!isOdd) {
try {
System.out.println("going to wait 2");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Odd: "+ i);
isOdd=false;
System.out.println("notify 2");
notifyAll();
}
}
}
}
As the main idea of your algorithm is not definitely clear for me, I'll just point out where is the bug & you can try to fix it by yourself.
When you start your threads one after another: p1.start(); p2.start(); they are executing in the same order as they we started.
When the first thread calls synchronized void run() method, than it locks the monitor on PrintEvenOdd.class. That means the second thread will wait until the first releases the monitor (say will not execute any single line of code).
Going further in debugger by the first thread execution flow you'll see operations below:
drop down into if(!isEven) condition
set isOdd=false during i=1 loop iteration
goes to endless wait() during i=2 loop iteration
As wait operation does not release the class monitor you're getting situation when both threads are suspended.

How can I start a thread from another and restart a thread after execution?

I have 2 threads, the "main" thread which starts a secondary thread to run a little process.
The "main" thread must wait for the secondary thread for a few of seconds to complete the process, after that time, the "main" thread must start again no matter what happened with the process of the secondary thread.
If the secondary process ended earlier, the "main" thread must start to work again.
How can I start a thread from another, wait for the end of execution, and restart the thread after?
I have a code here, but the ExampleRun class, must wait, for example, 10 sec and start again, no matter what happend with MyProcess
public class ExampleRun {
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
synchronized (t) {
try {
t.wait();
} catch (InterruptedException e) {
System.out.println("Error");
}
}
}
}
public class MyProcess extends Thread {
public void run() {
System.out.println("start");
synchronized (this) {
for (int i = 0; i < 5; i++) {
try {
System.out.println("I sleep");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = true;
System.out.println("Wake up");
notify();
}
}
}
The simplest way to achieve what you want is to use Thread.join(timeout).
Also, do not use synchronized, wait, or notify on Thread objects. This will interfere with the Thread.join implementation. See the documentation for details.
Here's what your main program would look like:
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
try {
t.join(10000L);
} catch (InterruptedException ie) {
System.out.println("interrupted");
}
System.out.println("Main thread resumes");
}
Note that when the main thread resumes after the join() call, it can't tell whether the child thread completed or whether the call timed out. To test this, call t.isAlive().
Your child thread of course could do anything, but it's important for it not to use synchronized, wait, or notify on itself. For example, here's a rewrite that avoids using these calls:
class MyProcess extends Thread {
public void run() {
System.out.println("MyProcess starts");
for (int i = 0; i < 5; i++) {
try {
System.out.println("MyProcess sleeps");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyProcess finishes");
}
}
You can do this with a simple lock method:
public static void main (String[] args)
{
// create new lock object
Object lock = new Object();
// create and start thread
Thread t = new Thread(() ->
{
// try to sleep 1 sec
try { Thread.sleep(1000); }
catch (InterruptedException e) { /* do something */ }
// notify main thread
synchronized (lock) { lock.notifyAll(); }
};
t.start();
// wait for second thread to finish
synchronized (lock)
{
while (t.isAlive())
lock.wait();
}
// second thread finished
System.out.println("second thread finished :)");
}
You could call Thread.join() on the Thread you want to wait for, per the Javadoc,
Waits for this thread to die.
Alternatively, you could use a Future and simply call get(), from its' Javadoc,
Waits if necessary for the computation to complete, and then retrieves its result.

Wait() / notify() synchronization

I'm trying to check how wait/notify works in java.
Code:
public class Tester {
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
synchronized (t) {
try {
System.out.println("wating for t to complete");
t.wait();
System.out.println("wait over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
synchronized (this) {
System.out.println("entering syncronised block");
notify();
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("leaving syncronized block");
}
System.out.println("leaving run method");
}
}
Output Returned
wating for t to complete
entering run method
entering syncronised block
//sleep called
leaving syncronized block
leaving run method
wait over
I was expecting when notify() is executed the wait will be over & System.out.println("wait over"); will get printed. But it seems it only gets printed when t finished its run().
Object monitor locks need to be performed a single reference of the same lock...
In your example you are waiting on an instance of the Thread, but using notify from the Runnable. Instead, you should use a single, common lock object...for example
public class Tester {
public static final Object LOCK = new Object();
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
synchronized (LOCK) {
try {
System.out.println("wating for t to complete");
LOCK.wait();
System.out.println("wait over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
synchronized (LOCK) {
System.out.println("entering syncronised block");
LOCK.notify();
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("leaving syncronized block");
}
System.out.println("leaving run method");
}
}
}
Output...
wating for t to complete
entering run method
entering syncronised block
leaving syncronized block
wait over
leaving run method
wait over and leaving run method could change positions depending on the thread scheduling.
You could try putting the sleep out side the synchronized block. This will release the monitor lock allowing the wait section to continue running (as it can't start until the lock is released)
public static class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
synchronized (LOCK) {
System.out.println("entering syncronised block");
LOCK.notify();
System.out.println("leaving syncronized block");
}
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("leaving run method");
}
}
Answer to updated code :
From Thread.sleep() javadoc:
Causes the currently executing thread to sleep (temporarily cease execution) for the
specified number of milliseconds, subject to the precision and accuracy of system timers
and schedulers. The thread does not lose ownership of any monitors.
If you call Thread.sleep while inside a synchronized block, other threads won't be able to enter the synchronized block. You should never do time consuming tasks while in a synchronized block to avoid this.
Note (as others pointed out as well) that you have to use the same object for locking/synchronizing in both threads.
If you want your main thread to continue immediately after notify is called, you have to relinquish the lock temporarily. Otherwise wait will get called only after the secondary thread leaves the synchronized block. And it's never a good idea to keep a lock in a long running computation!
One way how to achieve is to use wait(int) on the lock instead of sleep, because wait releases the synchronization lock temporarily:
public class Tester {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
synchronized (lock) {
try {
System.out.println("wating for t to complete");
lock.wait();
System.out.println("wait over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
synchronized (lock) {
System.out.println("entering syncronised block");
lock.notify();
try {
lock.wait(1000); // relinquish the lock temporarily
} catch (InterruptedException ex) {
System.out.println("got interrupted");
}
System.out.println("leaving syncronized block");
}
System.out.println("leaving run method");
}
}
}
However, using these low-level primitives can be very error prone and I'd discourage from using them. Instead, I'd suggest you to use Java's high-level primitives for that. For example, you can use CountDownLatch which lets one thread wait until other threads count down to zero:
import java.util.concurrent.*;
public class TesterC {
private static final CountDownLatch latch = new CountDownLatch(1);
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
System.out.println("wating for t to complete");
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait over");
}
static class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
try {
latch.countDown();
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("got interrupted");
}
System.out.println("leaving run method");
}
}
}
Here you don't have to synchronize anything, the latch does everything for you. There are many other primitives you can use - semaphores, an exchanger, thread-safe queues, etc. Explorer the java.util.concurrent package.
Perhaps even better solution is to use even higher level API, such as Akka provides. There you work with Actors or Software transactional memory, which can be composed easily and spare you of most of concurrency issues.

What if I am waiting on an object which is not Runnable?

Consider the following code :-
public class UsingWait1{
public static void main(String... aaa){
CalculateSeries r = new CalculateSeries();
Thread t = new Thread(r);
t.start();
synchronized(r){
try{
r.wait(); //Here I am waiting on an object which is Runnable. So from its run method, it can notify me (from inside a synchronized block).
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
System.out.println(r.total);
try{
Thread.sleep(1);
} catch (InterruptedException e){
System.out.println("Interrupted");
}
System.out.println(r.total);
}
}
class CalculateSeries implements Runnable{
int total;
public void run(){
synchronized(this){
for(int i = 1; i <= 10000; i++){
total += i;
}
notify(); // Line 1 .. Notify Exactly one of all the threads waiting on this instance of the class to wake up
}
}
}
Here I am waiting on CalculateSeries which is Runnable. So I can notify the waiting thread from the run() method of CalculateSeries.
But now, consider the following code where I am waiting on an object which is not Runnable.
public class WaitNotOnThread{
public static void main(String... aaa){
NotRunnable nr = new NotRunnable();
IAmRunnable r = new IAmRunnable(nr);
new Thread(r).start();
synchronized(nr){
try{
nr.wait();
} catch(InterruptedException e){
System.out.println("Wait interrupted");
}
System.out.println("After being notified within synchronized");
}
System.out.println("After synchronized");
}
}
class IAmRunnable implements Runnable{
NotRunnable nr;
IAmRunnable(NotRunnable nr){
this.nr = nr;
}
public void run(){
synchronized(nr){
try{
Thread.sleep(1000);
} catch(InterruptedException e){
System.out.println("Sleeping Interrupted :( ");
}
notify(); // Line 2
}
}
}
class NotRunnable{
}
Here I get an IllegalMonitorStateException at Line 2. I am waiting on the same instance of the object (which is not Runnable) while calling both, wait() as well as notify(). Then what is the problem?
Can someone also give some scenarios where it would be useful to wait on an object which is not Runnable??
Wait need not be on Runnable. That is why notify() is on Object and not on Runnable. I guess that helps in all cases we want to avoid busy wait.
The problem seems to be the synchronized() is on nr, and the notify is called on different object. Also synchronized should be on final variables.
class IAmRunnable implements Runnable {
final NotRunnable nr;
IAmRunnable( final NotRunnable nr) {
this.nr = nr;
}
public void run() {
synchronized (nr) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Sleeping Interrupted :( ");
}
nr.notify(); // Line 2
}
}
}

Categories