class firstThread extends Helper1
{
Thread thread_1 = new Thread(new Runnable()
{
#Override
public void run() {
try {
for (int i = 1; i <= 20; i++) {
System.out.println("Hello World");
Thread.sleep(500);
if (i == 10) {
Notify();
Wait();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
class secondThread extends firstThread
{
Thread thread_2 = new Thread(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
Wait();
for(int i = 1; i<=20; i++)
{
System.out.println("Welcome");
Thread.sleep(100);
}
Notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
class Helper1
{
public synchronized void Wait() throws InterruptedException
{
wait();
}
public synchronized void Notify() throws InterruptedException
{
notify();
}
}
public class InheritanceClass {
public static void main(String[] args)
{
Thread f = new Thread(new firstThread().thread_1);
Thread s = new Thread(new secondThread().thread_2);
f.start();
s.start();
}
}
Only the first Thread has an output. Please try my code. I don't know why it happens.
The second thread does not give output, I suppose it's because of Wait() in the secondThread, I don't know what to do.
The problem is with the following code:
class Helper1
{
public synchronized void Wait() throws InterruptedException
{
wait();
}
public synchronized void Notify() throws InterruptedException
{
notify();
}
}
Above, the wait() and notify() calls are equivalent to this.wait() and this.notify(). However, thread1 and thread2 are separate objects so they are not ever going to communicate via this method.
In order for communication to occur, you need a shared lock object. For example:
Object lock = new Object();
firstThread = new firstThread(lock);
secondThread = new secondThread(lock);
and synchronizations like:
void wait(Object lock) {
synchronized(lock) {
lock.wait();
}
}
void notify(Object lock) {
synchronized(lock) {
lock.notify();
}
}
Disclaimer: I would never do this personally, however it does answer the OP's question.
This code is really confusing, which is making it hard to see the underlying problem.
You should never start a class with a lower-case letter since it makes it look like a method/field name (e.g. firstThread).
I'm pretty sure Wait and Notify have no reason to be synchronized.
Why does secondThread inherit from firstThread??? Actually, why do you have those two classes at all? You should just make an anonymous inner class from Helper1 or something.
Anyway, the problem is that when you call Notify() in thread1 it notifies itself, not thread2.
Related
According to How to use wait and notify in Java? I have to synchronized on the same object to call notify.
I have synchronized on the same haveCoffee object. Why I am getting IllegalMonitorStateException when I call the notify method ?
I am Sleeping
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.example.concurrent.basic.WaitAndNotify$2.run(WaitAndNotify.java:42)
in the following code:
public class WaitAndNotify {
public static void main(String[] args) {
Thread haveCoffee = new Thread() {
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("I am awake and ready to have coffee");
}
}
};
Thread me = new Thread() {
public void run() {
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
haveCoffee.start();
me.start();
}
}
On the first Thread, you call wait on an object while having its monitor (the object being this haveCoffee).
However, on the second thread, you call notify() on me, while having the monitor of haveCoffee.
This should work:
public class WaitAndNotify {
public static void main(String[] args) {
final Thread haveCoffee = new Thread() {
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("I am awake and ready to have coffee");
}
}
};
Thread me = new Thread() {
public void run() {
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
haveCoffee.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
haveCoffee.start();
me.start();
}
}
From oracle documentation page,
public class IllegalMonitorStateException
extends RuntimeException
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
Whenever you get this exception, just go through your code and check wait() and notify() calls and the object on which these calls have been invoked. You can easily figure out what went wrong.
EDIT:
wait() or notify() calls have to be invoked on object once you get monitor on that object.
You should be calling
haveCoffee.notify()
instead of just
notify().
If you invoke just notify() it calls the notify() method on the this object which is the second thread me where as you have synchronized on haveCoffee thread and that is the reason for exception you are seeing.
So the code in thread2 me should looks like:
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
haveCoffee.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I know this question has been asked before, But I am unable to figure out why my solution is not working for me. I have two threads even and odd, one prints even numbers and other prints odd numbers. When I start the threads I want the output to be in natural order of numbers like 0 1 2 3..etc. This is my code:-
[updated]
public class ThreadCommunication {
public static void main(String... args) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread(){
#Override
public void run()
{
for(int i=0;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
obj.notify();
}
}
}
};
even.start();
odd.start();
}
}
when I run the above code, sometimes it prints the numbers in natural order as expected but sometimes it prints in some other order for ex:
0
1
3
5
7
9
2
What am I doing wrong here?
Edit:
volatile static boolean isAlreadyWaiting = false;
Thread even = new Thread() {
#Override
public void run() {
synchronized (obj) {
for (int i = 0; i < 10; i = i + 2) {
System.out.println(i);
try {
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
obj.notify();
isAlreadyWaiting=false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread() {
#Override
public void run() {
synchronized (obj) {
for (int i = 1; i < 10; i = i + 2) {
System.out.println(i);
try {
if(isAlreadyWaiting){
obj.notify();
isAlreadyWaiting = false;
}
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Check documentation
public class IllegalMonitorStateException extends RuntimeException
Thrown to indicate that a thread has attempted to wait on an object's
monitor or to notify other threads waiting on an object's monitor
without owning the specified monitor.
Monitor is owned by obj
So you should call
obj.wait();
and
obj.notify();
For more info on Ownership
This methods (wait or notify) should only be called by a thread that
is the owner of this object's monitor. A thread becomes the owner of
the object's monitor in one of three ways:
By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes
on the object.
For objects of type Class, by executing a synchronized static method
of that class.
Only one thread at a time can own an object's monitor.
#Pragnani Kinnera is right about the exception you're seeing. But if you want to alternate between even and odd, you'll need to move your second synchronized block into the loop. Otherwise, the notifying thread will hold the lock exclusively until the loop completes. (As opposed to the first thread, which yields its lock on each round.)
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
notify();
}
}
}
};
The first thread, however, should have the loop inside the synchronized block. If both threads release the lock, they both have an equal chance at reacquiring it. But if the first loop is inside the synchronized block, the second thread won't be able to reenter until the first has completed a full round and is waiting once again.
EDIT: This still won't work correctly, because there is no guarantee that the first thread won't reacquire the lock before the second thread does, per this quote from the documentation:
The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
You'll probably want to wake and notify from both threads to ensure they're in sync.
Here is your solution:
public class ThreadCommunication {
public static void main(String args[]) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread("Even Thread"){
#Override
public void run()
{
for(int i=0;i<10;i=i+2){
System.out.println(i);
synchronized(obj){
obj.notify();
}
synchronized(obj){
try {
obj.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
try {
synchronized(obj){
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
synchronized(obj){
obj.notifyAll();
}
}
}
};
even.start();
odd.start();
}
}
As explained by #shmosel, your synchronized block should only contain code that need to be synchronized.
I am trying to do it using two threads like below. Can someone point the obvious mistake I am doing here?
public class OddEven {
public static boolean available = false;
public static Queue<Integer> queue = new LinkedList<Integer>();
static Thread threadEven = new Thread() {
#Override
public void run() {
printEven();
}
public synchronized void printEven() {
while (!available) {
try {
wait();
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
System.out.println(queue.remove());
available = false;
notifyAll();
}
};
static Thread threadOdd = new Thread() {
#Override
public void run() {
printOdd();
}
public synchronized void printOdd () {
while (available) {
try {
wait();
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
System.out.println(queue.remove());
available = true;
notifyAll();
}
};
public static void main(String[] args) {
int n = 20;
for (int i = 1; i < n; i++) {
queue.add(i);
}
threadOdd.start();
threadEven.start();
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
threadOdd.join();
threadEven.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
But this program is only printing 1 and quitting. After printing 1 the available should be true and printEven should wake up, print and set available to false. I don't understand what is going wrong here? I saw other solutions but want to know why my solution is not working.
Putting synchronized on an instance method means that the thread calling that method has to acquire the lock on that instance; public void synchronized printOdd() is syntax sugar for
public void printOdd() {
synchronized(this) {
...
}
}
where this is different for each instance, since ThreadOdd and threadEven are two different objects and each one uses its own lock. The methods notifyAll and wait are called on the object that is being used as the lock. When one thread waits it never gets notified because the notification only applies to other threads waiting on the same lock as the notifying thread.
I was reading this post and the suggestions given to interrupt one thread from another is
" " " Here are a couple of approaches that should work, if implemented correctly.
You could have both threads regularly check some common flag variable (e.g. call it stopNow), and arrange that both threads set it when they finish. (The flag variable needs to be volatile ... or properly synchronized.)
You could have both threads regularly call the Thread.isInterrupted() method to see if it has been interrupted. Then each thread needs to call Thread.interrupt() on the other one when it finishes." " "
I do not understand how the second approach is possible that is using Thread.isInterrupted().
That is, how can Thread-1 call Thread.interrupt() on Thread-2.
Consider this example, in the main method I start two threads t1 and t2. I want t1 to stop t2 after reaching certain condition. how can I achieve this?
class Thread1 extends Thread {
public void run(){
while (!isDone){
// do something
}
} //now interrupt Thread-2
}
class Thread2 extends Thread {
public void run(){
try {
while(!Thread.isInterupted()){
//do something;
}
catch (InterruptedExecption e){
//do something
}
}
}
public class test {
public static void main(String[] args){
try {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
t2.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The context of this is that you are trying to implement your scheme using thread interrupts.
In order for that to happen, the t1 object needs the reference to the t2 thread object, and then it simply calls t2.interrupt().
There are a variety of ways that t1 could get the reference to t2.
It could be passed as a constructor parameter. (You would need to instantiate Thread2 before Thread1 ...)
It could be set by calling a setter on Thread1.
It could be retrieved from a static variable or array, or a singleton "registry" object of some kind.
It could be found by enumerating all of the threads in the ThreadGroup looking for one that matches t2's name.
public class test {
private static boolean someCondition = true;
public static void main(String[]args){
Thread t2 = new Thread(new someOtherClass("Hello World"));
Thread t1 = new Thread(new someClass(t2));
t2.start();
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static class someClass implements Runnable{
Thread stop;
public someClass(Thread toStop){
stop = toStop;
}
public void run(){
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(someCondition && !stop.isInterrupted()){
stop.interrupt();
}
}
}
}
static class someOtherClass implements Runnable{
String messageToPrint;
public someOtherClass(String s){
messageToPrint = s;
}
public void run(){
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(messageToPrint);
}
}
}
}
You could consider the use of Future interface. It provides a cancel() method.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
Playing with interruption makes your life unnecessarily hard. Besides the fact that your code must know the threads, interruption does not provide any context information about the reason of the interruption.
If you have a condition that is shared by your code possibly executed by different threads, just encapsulate that condition into an object and share that object:
public class Test {
public static void main(String[] args) {
Condition c=new Condition();
new Thread(new Setter(c)).start();
new Thread(new Getter(c, "getter 1")).start();
// you can simply extend it to more than one getter:
new Thread(new Getter(c, "getter 2")).start();
}
}
class Getter implements Runnable {
final Condition condition;
final String name;
Getter(Condition c, String n) { condition=c; name=n; }
public void run() {
while(!condition.isSatisfied()) {
System.out.println(name+" doing something else");
try { Thread.sleep(300); } catch(InterruptedException ex){}
}
System.out.println(name+" exiting");
}
}
class Setter implements Runnable {
final Condition condition;
Setter(Condition c) { condition=c; }
public void run() {
System.out.println("setter: doing my work");
try { Thread.sleep(3000); }
catch(InterruptedException ex){}
System.out.println("setting condition to satisfied");
condition.setSatisfied();
}
}
class Condition {
private volatile boolean satisfied;
public void setSatisfied() {
satisfied=true;
}
public boolean isSatisfied() {
return satisfied;
}
}
The big advantage of this encapsulation is that it is easy to extend. Suppose you want to allow a thread to wait for the condition instead of polling it. Taking the code above it’s easy:
class WaitableCondition extends Condition {
public synchronized boolean await() {
try {
while(!super.isSatisfied()) wait();
return true;
} catch(InterruptedException ex){ return false; }
}
public synchronized void setSatisfied() {
if(!isSatisfied()) {
super.setSatisfied();
notifyAll();
}
}
}
class Waiter implements Runnable {
final WaitableCondition condition;
final String name;
Waiter(WaitableCondition c, String n) { condition=c; name=n; }
public void run() {
System.out.println(name+": waiting for condition");
boolean b=condition.await();
System.out.println(name+": "+(b? "condition satisfied": "interrupted"));
}
}
Without changing the other classes you can now extend your test case:
public class Test {
public static void main(String[] args) {
WaitableCondition c=new WaitableCondition();
new Thread(new Setter(c)).start();
new Thread(new Getter(c, "getter 1")).start();
// you can simply extend it to more than one getter:
new Thread(new Getter(c, "getter 2")).start();
// and you can have waiters
new Thread(new Waiter(c, "waiter 1")).start();
new Thread(new Waiter(c, "waiter 2")).start();
}
}
hello guys this is my code , problem am facing is that despite calling notifyAll, it is not releasing the lock , can you please state the reason and tell the solution. Am new to threads. Thanks in advance.
class Lock1 {}
class Home1 implements Runnable {
private static int i = 0;
private Lock1 object;
private Thread th;
public Home1(Lock1 ob, String t) {
object = ob;
th = new Thread(this);
th.start();
}
public void run() {
synchronized (object) {
while (i != 10) {
++i;
System.out.println(i);
}
try {
// System.out.println("here");
object.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("here thread 1");
}
}
}
class Home2 implements Runnable {
private static int i = 0;
private Lock1 object;
Thread th;
public Home2(Lock1 ob, String t) {
object = ob;
th = new Thread(this);
th.start();
}
public void run() {
synchronized (object) {
while (i != 10) {
++i;
System.out.println(i);
}
try {
// System.out.println("here");
object.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("here thread 2");
}
}
}
public class Locking {
public static void main(String arg[]) {
Lock1 ob = new Lock1();
new Home1(ob, "thread 1");
new Home2(ob, "thread 2");
synchronized (ob) {
ob.notifyAll();
}
}
}
When you use notifyAll, you should also have a state changed and when you use wait, you should check that state change.
In your case it is likely that notifyAll will be called long before the threads really have time to start. (For a computer, starting a thread takes an eternity, like 10,000,000 clock cycles) This means the notifyAll is lost. (It only notifies threads which are actually waiting right at that moment)