I have developed a program in which the thread A waits for Thread B to complete it task and when thread B finishes its task it makes notfiy() to thread A to continue onwards..below is the code..
class ThreadA {
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(b) {
try {
System.out.println("Waiting for b to complete...");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.totals);
}
}
}
class ThreadB extends Thread {
public int totals;
public void run() {
synchronized(this) { //instance level lock
for(int i=0;i<100;i++) {
totals += i;
}
notify();
}
}
}
Now I want lets say 3 more thread are waiting for thread b , so please advise me how to spawn 3 more threads , just like thread A is waiting , please advise.
Use the ExecutorService it has a methode invokeAll(). You can submit all your ThreadB and hold a List of Future's.
Your current code actually contain possible deadlock since you start() the threadB first and it is calling the notify() in its run(). This notify() is possible to be called before the wait() in the main. If this happens, you threadB will be waiting forever.
To start more ThreadB, you just need to create more instances.
ThreadB threadBs = new ThreadB[3];
for (ThreadB b : threadBs) {
b = new ThreadB();
b.start();
}
However, I will suggest implementing the Runnable interface instead of just extending the Thread class.
Related
Consider the following code:
public class MyObject{
synchronized void f() {
System.out.print("a ");
System.out.print("b ");
}
synchronized void g() {
System.out.print("z ");
System.out.print("x ");
}
void h() {
System.out.print("1 ");
System.out.print("2 ");
}
}
Thread 1 class
public class Thread1 implements Runnable {
MyObect myObject;
Thread1(MyObject t){
MyObject = t;
}
public void run() {
myObject.f();
}
}
Thread 2 class
public class Thread2 implements Runnable {
MyObect myObject;
Thread2(MyObject t) {
myObject = t;
}
public void run() {
myObject.g();
myObject.g();
}
}
Main method:
public static void main(String[] args) {
MyObject myObj = new MyObject();
Thread1 t1 = new Thread(new Thread1(myObj));
Thread1 t2 = new Thread(new Thread1(myObj));
t1.start();
t2.start();
}
When you run the main class, would all the possible outputs be
a b z x z x
z x z x a b
Or can Thread2 sleep in the middle which would result in something like
z x a b z x
Yes, it can sleep in the middle so all three are possible because it releases the lock after each call to g. Otherwise those methods are synchronized and guaranteed to run in their entirely.
Yes, it is possible to get something like zxabzx because you release the lock and require it in Thread 2
Remember that a Thread can always yield the processor (CPU/GPU) to another thread in the middle of its execution which is something very common when the thread executes for a long period of time ("long" meaning a couple of milliseconds)
can Thread2 sleep in the middle ?
Yes, it can, Thread 2 will have to release lock on MyObect as soon as execution of first g() completes.
So, It can allow other thread to take lock on MyObect before proceeding with the next g()
I have two classes that extend Thread and a wait/notify
class A extends Thread {
int r = 20;
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
notify();
}
}
}
class B extends Thread {
A a;
public B(A a) {
this.a = a;
}
public void run() {
synchronized (a) {
System.out.println("Starting...");
try {
a.wait();
} catch (InterruptedException e) {
}
System.out.println("Result is: " + a.r);
}
}
}
Class A notifies Class B upon end of execution
A a = new A();
new B(a).start();
new B(a).start();
new B(a).start();
And the following code
a.start();
Notifies all threads
new Thread(a).start();
Notifies one thread
Why does a.start() notify all threads?
It's not
a.start();
that notifies all threads. It's the fact that the thread referenced by a terminates that notifies all threads waiting on its monitor.
This is explained in the javadoc
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
On the other hand, in
new Thread(a).start();
you're using a as a Runnable, not as a Thread. The actual thread that will invoke this.notifyAll is the one created by the instance creation expression new Thread(a), which no other thread has called Object#wait() on.
Please see the below code, where the notifyAll is commented. Still the main thread is printing the total? How is it possible?
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}}
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
// notify();
}
}
}
What you see is the result of something documented in the javadoc of Thread.join():
As a thread terminates the this.notifyAll method is invoked.
Note that it goes on with
It is recommended that applications not use wait, notify, or notifyAll on Thread instances
Also note that a thread blocked on wait() can go out of its waiting state without any notification, due to spurious wakeups. And the javadoc of wait() clearly explains that wait() should always be called inside a loop.
Also note: The Java API doc for Object.wait() says, "...interrupts and spurious wakeups are possible, and this method should always be used in a loop."
That is generally true in other APIs and other languages as well. A method/function should never assume that the condition it was waiting for is true just because a wait() operation on a condition variable returned. There should always be a loop. In pseudo-code:
lock mutex
while (! ok_to_do_whatever()) {
wait on condition_variable
}
do_whatever()
unlock mutex
Try this and the waiting thread will wait forever...
public class ThreadA {
public static Object lock = new Object();
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(lock){
try{
System.out.println("Waiting for b to complete...");
lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread
{
int total;
#Override
public void run(){
synchronized(ThreadA.lock){
for(int i=0; i<100 ; i++){
total += i;
}
// notify();
}
}
}
I am trying to implementing deadlock condition but somehow I am not able to get it working. Both the threads Thread1 and Thread2 are entering in the run function but only one of them enters in Sub/Sum depending on who entered run first. Example : if Thread2 entered run first the it will call sub() and Thread1 never calls sum(). I have also added sleep time so that Thread2 sleeps before calling sum() and Thread1 gets enough time to enter Sum() but Thread1 never enters.
public class ExploringThreads {
public static void main(String[] args) {
// TODO Auto-generated method stub
threadexample a1 = new threadexample();
Thread t1 = new Thread(a1, "Thread1");
Thread t2 = new Thread(a1,"Thread2");
t1.start();
t2.start();
}
}
class threadexample implements Runnable{
public int a = 10;
public void run(){
if(Thread.currentThread().getName().equals("Thread1"))
sum();
else if(Thread.currentThread().getName().equals("Thread2"))
sub();
}
public synchronized void sum()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sum");
sub();
}
public synchronized void sub()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sub");
sum();
}
}
If you really want to create an artificial dead lock, try this:
Thread1 and Thread2 are two threads that want to access the same file.
Thread1 starts, asks for a lock on File1.docx and sleeps for 2 minutes.
Thread2 starts, and makes an exclusive lock on File2.docx and now wants to access File1.docx.
Thread1 wakes up and now wants to access File2.docx which is held by Thread2
Now, this is a circular wait condition
Simple ? =)
This is not how you get a deadlock. Actually this code seems pretty safe :-) Only one thread enters sum/sub at a time because you are using synchronized which synchronizes on "this". There is only one "this" so both threads try to acquire the same lock.
Deadlock occurs, for instance, when Thread1 has one lock, Thread2 has second lock and then Thread1 would like to acquire Thread2's lock while still holding it's lock and Thread2 would like to acquire Thread1's lock while still holding it's lock.
What you could do is:
a) add 2 objects for locking in "threadexample" class (btw classes by convention should start with uppercase):
private final Object sumLock = new Object();
private final Object subLock = new Object();
b) drop the "synchronized" keyword in both sum/sub methods and instead use the synchronized() {} block in each of them. Sum would be synchronized(sumLock) { /* sum's body goes here / } and sub would be synchronized(subLock) { / sub's body goes here */}.
In this case Thread1 would go into sum(), acquire the sumLock and wait. Thread2 would go into sub(), acquire the subLock() and wait. Thread1 would wake up, go into sub() and try to acquire subLock but it's being held by Thread2 so it wait's until Thread2 releases it. In that time Thread2 wakes up, goes into sum() and tries to acquire sumLock which is held by Thread1 so Thread2 waits for Thread1 to release it.
Neither thread will go forward as each one of them is waiting for the other - you have a deadlock.
#Edit: yes you have only 1 instance of "threadexample" and both Thread1 and Thread2 are fighting for the lock but when one of them acquires the lock it will release it after executing sum/sub or sub/sum. For instance let's say Thread1 is first and starts executing sum(). It has the lock. In that case Thread2 will not go into sub() as it is protected by the same lock as Thread1. Thread1 will do sum(), then sub() and then it will release the lock --> Thread2 will go into sub() etc.
This is a working example of 'Deadlock in Action'. Basically what you need to do (and how that usually happens in real world) is that object are locked in opposite order: a first, b second in one thread and b first, a second in another:
package stackoverflow;
public class Deadlock {
final static String a = new String("A");
final static String b = new String("B");
public static void main(String[] args) {
final Thread abLock = new Thread() {
#Override
public void run() {
lock(a, b);
}
};
final Thread baLock = new Thread() {
#Override
public void run() {
lock(b, a);
}
};
abLock.start();
baLock.start();
}
static void lock(String first, String second) {
synchronized (first) {
System.out.println(first);
sleep();
synchronized (second) {
System.out.println(second);
}
}
}
static void sleep() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Here is a code i am having problem with --
public class WaitTest {
public static void main(String[] args) {
Runner rr = new Runner();
Thread t1 = new Thread(rr,"T1");
Thread t2 = new Thread(rr,"T2");
t1.start();
t2.start();
}
}
class Runner implements Runnable{
int i=0;
public void run(){
try{
if(Thread.currentThread().getName().equals("T1")){
bMethod();
aMethod();
}
else{
aMethod();
bMethod();
}
}catch(Exception e){}
}
public synchronized void aMethod() throws Exception{
System.out.println("i="+i+",Now going to Wait in aMethod "+Thread.currentThread().getName());
Thread.currentThread().wait();
System.out.println("Exiting aMethod "+Thread.currentThread().getName());
}
public synchronized void bMethod() throws Exception{
System.out.println("i="+i+",Now going to Wait bMethod "+Thread.currentThread().getName());
i=5;
notifyAll();
System.out.println("Exiting bMethod "+Thread.currentThread().getName());
}
}
The output is :
i=0,Now going to Wait bMethod T1
Exiting bMethod T1
i=5,Now going to Wait in aMethod T1
i=5,Now going to Wait in aMethod T2
My question is :
Why T2 enters in aMethod while T1 is waiting inside? and Why T2 prints
i=5 in aMethod.
When you execute wait, your thread releases the lock and enters the wait state. At this time the other thread is allowed to enter the method. You are using a single instance of Runnable so when one thread sets it to 5, that's what the other thread reads.
1. wait will immediately release the lock, and handover the lock to the other thread.
2. notify will release the lock only when the closing parenthesis of the synchronized block
is reached.
3. As there is only one instance of Runnable here, its after the i = 5, and when the synchronized block ends..then the lock is released.
This code is not doing the wait-notify pattern. The Thread.currentThread().wait() call throws an IllegalMonitorStateException, which is caught and ignored by the run method. Both T1 and T2 throws this exception, and hence you do not see the line Exiting aMethod printed.
The notify call in bMethod is wasted, because no thread ever waits on the intrinsic lock of the rr Runnable.