Printing Two Different Strings in two Threads in Order - java

I am trying to Write a Program where two threads are running simultaneously. One is printings Jack and other is Jones. The expected output is :
Jack Jones Jack Jones and so on. But I am facing issue while doing calling notifyAll(). Can anyone tell me what is the problem ?
Exception
Starting thread
Jack Jones Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at JonesThread.printJones(JonesThread.java:32)
at JonesThread.run(JonesThread.java:14)
java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at JackThread.printJack(JackThread.java:36)
at JackThread.run(JackThread.java:15)
Jack Thread
import java.util.concurrent.atomic.AtomicBoolean;
public class JackThread extends Thread {
AtomicBoolean i;
public JackThread(AtomicBoolean i2) {
this.i = i2;
}
public void run() {
while (true) {
try {
printJack();
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void printJack() throws InterruptedException {
synchronized (i) {
while (i.get()) {
{
wait();
}
}
System.out.print("Jack ");
i.set(true);
notifyAll();
}
}
}
Jones Thread
import java.util.concurrent.atomic.AtomicBoolean;
public class JonesThread extends Thread {
AtomicBoolean i;
public JonesThread(AtomicBoolean i2) {
this.i = i2;
}
public void run() {
while (true) {
try {
printJones();
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void printJones() throws InterruptedException {
synchronized (i) {
while (!i.get()) {
wait();
}
System.out.print("Jones ");
i.set(false);
notifyAll();
}
}
}
MainProgram
import java.util.concurrent.atomic.AtomicBoolean;
public class ThreadMain {
public static void main(String args[]) {
AtomicBoolean i = new AtomicBoolean(false);
System.out.println("Starting thread");
JackThread t1 = new JackThread( i); // Will give chance to Print Jack first
JonesThread t2 = new JonesThread(i);// Jones will follow Jack
t1.start();
t2.start();
}
}

The definition of wait is that if you say
someObject.wait();
the thread will wait until somebody notifies someObject's monitor. Another thread can do that by calling
someObject.notify(); // or notifyAll
The thing is, though, the threads have to coordinate by using the same object. You haven't specified an object, so your wait() is equivalent to
this.wait();
That is, the JackThread object is waiting for somebody to notify itself. But nobody is notifying the JackThread object. When your JonesThread calls notifyAll(), it's the same as
this.notifyAll();
so it's notifying itself, i.e. a JonesThread object. So basically, your two threads are talking to themselves and not to each other.
It looks like you've set up i as an object that is known to both threads, so you could use that for your wait and notify, i.e. i.wait(), i.notifyAll(). Disclaimer: I haven't tested it.

Related

Java Thread Class : java.lang.IllegalMonitorStateException

This is my first post so sorry if I do something wrong.
I'm trying to understand how work the threads in Java, in particular the synchronization, that's why I created a little piece of code which is supposed to print 1, 2, 3, 4, 5, 6 (in one thread) and then a second thread wait that's the first finished and then print 6, 5, 4, 3, 2, 1 but it only do the first 6 steps and tell me that there is a monitor problem for the wait method in the thread t2 and a problem with the notify all of the thread t1. Maybe I haven't understood anything about the synchronization of an object. Here is my code :
public class anObject extends Thread {
long value;
String name;
public anObject(long value, String name) {
this.value = value;
this.name = name;
}
public synchronized void add() {
this.value++;
}
public synchronized void sub() {
this.value--;
}
public static void main(String[] args) {
anObject il = new anObject(0, "Bob");
synchronized (il) {
Thread t1 = new Thread(il) {
public void run() {
while (il.value > 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 6; i++) {
il.add();
System.out.println(il.value);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
il.notifyAll();
}
};
Thread t2 = new Thread(il) {
public void run() {
while (il.value < 6) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 6; j++) {
il.sub();
System.out.println(il.value);
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
il.notifyAll();
}
};
t1.start();
t2.start();
}
}
}
And this is what appeared in the terminal :
Exception in thread "Thread-2" 1
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at anObject$2.run(anObject.java:53)
2
3
4
5
6
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at anObject$1.run(anObject.java:45)
Thanks a lot for your help!
Greetings
wait is defined in Object, this is why you get this exceptions.
I prefer dedicated lock for avoid the unpredictable monitor exceptions:
private final Object lock = new Object();
private static final class Lock { }
private final Object lock = new Lock();
For notify or notifyAll an object, you need to be holding the lock with the synchronized statement. Also, you should define a loop to check for the wakeup condition.
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
To notify:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
What you are doing by this
synchronized (il)
is just grabbing an object's monitor from the main thread. But inside you are initializing two new threads and trying to call the wait() method from the contexts of both of these recently initialized and then started threads. The main idea of IllegalMonitorStateException is that you are trying to call a method that uses a context of object's locking without preceding obtaining of this object's lock. What you can do to fix it fast is just to change
while (il.value > 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
on
while (il.value > 0) {
try {
synchronized(this) {
this.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
and to make an equal change in the second block of code. But to really make it right, I would recommend you to turn to some strong sources describing multithreading concept. Oracle's basic java tutorial will be just fine I suppose.

Calling method of blocked thread

I'm just starting to learn about multithreading in Java, and am still figuring some things out. Firstly, can a class that extends Thread have other instance methods associated with it that can be called during its execution---and if so, can it change the state of the thread during its execution? Secondly, if this class is blocked waiting for a semaphore, can its instance methods still be called? Something like having these 2 threads run:
Thread1 t;
public class Thread1 extends Thread {
private int num;
public run() {
sem.acquire(); // here it blocks waiting for another thread
//to call its setInt function and release it
System.out.println("num is " + num);
}
public void setInt(int i) {
num = i;
}
}
public class Thread2 extends Thread {
public run() {
t.setInt(5);
sem.release();
}
}
There is some confusion here.
Threads don't have methods. Classes have methods.
Classes aren't blocked. Threads are blocked.
You can call any method any time. The method itself may be synchronised, which will delay entry to it, or it may used synchronization internally, ditto, or semaphores, ditto.
To demonstrate what you are looking for, here is the a code example wich I tested:
package test2;
import java.util.concurrent.Semaphore;
public class mainclass {
static Thread1 t;
static Semaphore sem;
static Semaphore sem_protect;
public synchronized static void main (String[] args) {
sem = new Semaphore(0);
sem_protect = new Semaphore(1);
t = new Thread1();
Thread1 th1 = new Thread1();
th1.start();
Thread2 th2 = new Thread2();
th2.start();
try {
synchronized (th2){
th2.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("The end !");
}
public static class Thread1 extends Thread {
private int num;
public void run() {
try {
sem.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // here it blocks waiting for another thread
//to call its setInt function and release it
try {
sem_protect.acquire();
System.out.println("num is " + num);
sem_protect.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized void setInt(int i) {
try {
sem_protect.acquire();
this.num = i;
sem_protect.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("value of num is: "+num);
}
}
public static class Thread2 extends Thread {
public void run() {
t.setInt(5);
sem.release();
}
}
}
Here is the result of execution of this code:
value of num is: 5
The end !
num is 0
With this result you can see that you can still access the methods of the class thread1 from the Thread2 . It means you access the method of the class instance, there is no method for a thread. (this is an answer for your first question)
The state of first thread is not changed by the second, num is still 0 for the first thread, the threads have each their own context.
even if we protect the access to num with another semaphore we dont have the same num value for the two threads.

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.

Having troubles with threads and semaphors in JAVA

I am new to threading and semaphors, and I have some problem in synchronizing threads. For example, in the following code I want to do a pretty simple thing. To let one thread run, while other waits. For example, if it starts with the first thread, I want the second to wait for the first one to finish and then start. I really don't know what am I doing wrong.
Here is the code :
import java.io.*;
import java.util.concurrent.Semaphore;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Semaphore binaren = new Semaphore(1);
Runnable t1 = new T2(binaren);
Thread a = new Thread(t1);
Thread a2 = new T1(binaren);
System.out.println(binaren.availablePermits());
a.start();
a2.start();
}
}
class Work {
private static int a = 4;
public synchronized static void QQR(String s1)
{
for(int i=0;i<100;i++)
System.out.println(s1+" : "+(a++));
}
}
class T1 extends Thread
{
Semaphore sem;
public T1(Semaphore s1)
{
sem=s1;
}
public void run()
{
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T1");
sem.release();
notifyAll();
}
}
}
class T2 extends Thread
{
Semaphore sem;
public T2(Semaphore s1)
{
sem=s1;
}
#Override
public void run() {
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T2");
sem.release();
notifyAll();
}
}
}
The problem is that notify and notifyAll only wake up threads holding locks on the monitor being notified. But the t1 and t2 instances are waiting on themselves and are never awoken. You can have them wait on the semaphore for this simple test or introduce a new shared object to see how it works.
Use
sem.wait();
and
sem.notifyAll();
You can use Thread.join() on the first thread so that second thread will wait till the execution of this instance is not completed.

Notify not getting the thread out of wait state

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.

Categories