Threads logic in Java - java

I'm trying to resolve a university exercise. The class AImpl has a method ma(B b) that creates and runs two threads. These threads have to call mb1() and mb2() (they are simple methods that just print a text, so I didn't include them). The calling thread should then wait for mb1() to terminate before finishing.
My logic is:
The first thread enters and after finishing the execution of b.mb1() starts to wait() on the current object, releasing the mutex. Then the second thread runs and it does the same. When they are both waiting, the calling thread calls notifyAll() on the object, waking both of them. They execute b.mb2() and then terminate.
The problem is that when the first thread starts waiting with object.wait(), the control flow doesn't return on the calling thread and the program enters in a deadlock.
Where is my logic flawed?
public class AImpl{
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
BImpl b = new BImpl();
AImpl.ma(b);
}
public static void ma(B b) throws InterruptedException {
Thread thread = new Thread() {
#Override
public void run() {
b.mb1();
synchronized(object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
b.mb2();
System.out.println("Thread finished");
}
};
Thread thread1 = new Thread() {
#Override
public void run() {
b.mb1();
synchronized(object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
b.mb2();
System.out.println("Thread finished");
}
};
thread.run();
thread1.run();
synchronized(object){
object.notifyAll();
}
System.out.println("Program finished.");
}
}

The notify/notifyAll methods tell the scheduler to notify one/all of the threads currently waiting on the lock that notify or notifyAll was called on. But if a thread hasn't started waiting yet then it doesn't get notified.
The solution is to introduce a condition variable that keeps wait from being called if the notifying has happened already. Define it in the same scope as your lock:
public static volatile boolean ready = false;
Then use it to guard the wait block, like this:
while (!ready) {
object.wait();
}
The code calling notify/notifyAll needs to set the variable (it doesn't matter what order you do it in because the notification doesn't happen until the lock is released):
synchronized (object) {
ready = true;
object.notifyAll();
}
What happens:
If the waiting thread gets to the waiting part before the notifying thread does its notifying, then the waiting thread finds ready is false, so it enters the wait method, releases the lock, and stays there. Then the notifying thread changes the flag to true and wakes up the waiting thread, which can leave the wait, reacquire the lock, and then leave the loop now that the flag is set.
But if the notifying thread does its notify before the other thread waits, that's ok, because the ready flag now prevents the thread from entering the wait, it can skip over it.
Further reading: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

Related

precise behaviour of interrupt() method with respective to thread states in java

I have read the post below
What does java.lang.Thread.interrupt() do? but i have not been able to get it completely right
I quote from #Mike_q answer to above question as below
Thread.interrupt() sets the interrupted status/flag of the target thread. Then code running in that target thread MAY poll the interrupted status and handle it appropriately. Some methods that block such as Object.wait() may consume the interrupted status immediately and throw an appropriate exception (usually InterruptedException)
It says while object is in WAITING it can consume interrupted status, so what happens when it is BLOCKED state waiting for object's lock ... ?
i have experimented below with that scenario and code is
at X: t2 is blocked
public class interruptsyc
{
static Object resource = new Object();
public static void main(String []args)
{
System.out.println("started main");
Thread1 t1=new Thread1("thread 1");
t1.start();
delay(1000);
Thread2 t2 =new Thread2("thread 2");
t2.start();
delay(1000);
t2.interrupt(); // X: at this point t2 is in blocked state waiting for resource's lock
System.out.println(t2.getName()+t2.interrupted());
delay(1000);
System.out.println("end main");
}
static void delay(long n)
{
try
{
Thread.sleep(n);
}
catch(InterruptedException ex)
{
System.out.println(Thread.currentThread().getName()+Thread.interrupted());
ex.printStackTrace();
}
}
static class Thread1 extends Thread{
Thread1(String name)
{
setName(name);
}
public void run()
{
synchronized(resource)
{
System.out.println("start 1");
delay(6000);
System.out.println("end 1");
}
}
}
static class Thread2 extends Thread{
Thread2(String name )
{
setName(name);
}
public void run()
{
synchronized(resource)
{
System.out.println("start 2");
delay(2000);
System.out.println("end 2");
}
}
}
}
and output has below
started main
start 1
false
end main
end 1
start 2
thread 2false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at interruptsyc.delay(interruptsyc.java:25)
at interruptsyc$Thread2.run(interruptsyc.java:59)
end 2
it seems that InterruptedException has been called ,when sleep method is called later... why is that ...?
again what is polling i didn't quite understand from what is said here
Polling occurs via the Thread.interrupted() method which returns the current thread's interrupted status AND clears that interrupt flag. Usually the thread might then do something such as throw InterruptedException.
again whenever i called Thread2.interrupted() method in above code it returned false (when i called just after t2.interrupt and in catch block)
it seems that InterruptedException has been called ,when sleep method is called later... why is that ...?
Because blocking/sleeping methods don't block immediately. They first check if the thread has been interrupted, and if it has been, they throw an InterruptedException immediately, in order for the thread to stop ASAP.
whenever i called Thread2.interrupted() method in above code it returned false
Because when blocking/sleeping methods throw an InterruptedException, they also clear the interrupt flag.
This is in the javadoc of Thread.sleep():
Throws InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

how to stop a thread with thread interrupt method

I am trying to learn thread interrupt and how to make a thread terminate without calling stop.
public class Test implements Runnable{
static Thread threadTest=null;
public static void main(String args[]){
System.out.println("Hello i am main thread");
Test thread= new Test();
threadTest= new Thread(thread);
threadTest.start();
}
private static void exitThread() {
threadTest.interrupt();
}
#Override
public void run() {
boolean run = true;
while (run) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
run = false;
}
}
}
}
Output
Hello i am main thread
Sleeping
Processing
Sleeping
I am unable to understand why Sleeping is printed second time and interrupted exception is thrown second time rather than first time.I have checked posts where volatile keyword is used to stop a thread in java.but i am unable to understand how that will be used in this scenario as thread gets stopped with interrupt.
In order to see the thread being interrupted instead of entering the sleep method a second time, change the while loop test in the run method to check the interrupt flag:
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
The thread will sleep, then set its own interrupt flag, then check the flag and terminate. InterruptedException would be thrown by the Thread#sleep method only if the thread was sleeping while the interrupt flag was set.
Your local boolean variable is not needed. If Thread#sleep throws an InterruptedException (which it won't in this example because the thread checks the interrupted flag and leaves the while loop) then the interrupt flag is cleared, restoring it in the catch block allows the while test to see that the thread was interrupted.
In real programs the thread would be interrupted from another thread, there's no reason for a thread to interrupt itself (it can just return instead).
Calling Thread.interrupt() just sets a flag for the thread. It doesn't do anything else. Only blocking methods (those usually declare throws InterruptedException) respond to that flag being set (by throwing). The flag is sticky in that it remains set until its cleared.
So the first call to the sleep method just runs normally (the interrupted flag isn't set yet). After that your code does nothing that acts on the interrupted status, until the second loop iteration where the sleep call detects the interrupted status and throws the exception.
You can use Thread.interrupted() or Thread.isInterrupted() to check the interrupted status at any time (beware that interrupted() also clears the interrupted status if it was set).
here you creating another thread Test class but "main" has its own thread , so the new thread you created is interpreted .
Here in this code you are interrupting the new created thread Thread-0 not main thread,when you execute this code you are making thread to sleep before it enters the method exitThread() ,so it is displaying the processing, but if you try to put thread sleep after you enter exitthread() you will have your answer
Like in this code:
public class Test implements Runnable {
public boolean run = true;
#Override
public void run() {
while (run) {
try {
System.out.println("Sleeping...");
exitThread();
Thread.sleep(10000);
System.out.println("Processing...");
} catch (InterruptedException e) {
System.out.println("Thread intreputted " + e);
run = false;
}
}
}
private void exitThread() {
Thread.currentThread().interrupt();
if (Thread.currentThread().isInterrupted())
System.out.println(Thread.currentThread().getName()
+ " is intreputted");
else
System.out.println("alive");
}
public static void main(String[] args) {
System.out.println("hi I am current thread------>"
+ Thread.currentThread().getName());
Test test = new Test();
Thread thread = new Thread(test);
thread.start();
}
}
Hope it will be helpfull

Notification in thread

Will the thread give up the monitor immediately as soon as the notify() method is invoked like as it happens in wait(). Or when the notify() is invoked, will the monitor be released after the execution of the method is completed.
To which state will the thread move into when notify() is invoked. Waiting or Blocked state ?
The thread owning the monitor will continue to hold the monitor in case of notify().
notify()/notifyAll() just informs waiting thread that they can optain the lock again. Once a thread obtains the monitor it will exit the wait() method and continue.
To sum up: Thread involving notify()/notifyAll() will stay on RUNNING state as soon as the lock releases naturally (out of synchronized block/method).
The goal of notification is just to authorize waiting threads a future chance to get the lock as soon as this one is available.
A thread holds the monitor for an object as long as it is synchronized on that object. A notified thread will move to the BLOCKED state, and will obtain the monitor once the owning thread releases it by leaving the synchronized block/method that previously held the monitor.
For example, if thread A is blocking on a call to lock.wait() and thread B calls lock.notify(), thread A will leave the WAITING state and enter the BLOCKING state**, however thread A will not resume execution (i.e. enter the RUNNABLE state) until thread B leaves the synchronized block for lock.
** Assumes there are no other threads waiting on lock since the order that threads are notified is not guaranteed, which is why you should use notifyAll() as a rule (unless you know what you're doing and have a good reason not to).
Using code:
public class ThreadStateTest {
private static final Object lock = new Object();
public static void main(String[] args) {
synchronized (lock) {
new Thread(new RunnableTest()).start();
try {
Thread.sleep(1000);
System.out.println("this will print first");
lock.wait();
System.out.println("this will print third");
} catch (InterruptedException ex) {
}
}
}
private static class RunnableTest implements Runnable {
#Override
public void run() {
try {
synchronized (lock) {
lock.notifyAll();
Thread.sleep(1000);
System.out.println("this will print second");
}
Thread.sleep(1000);
System.out.println("this will print fourth");
} catch (InterruptedException ex) {
}
}
}
}

Deadlocks using wait and notify

I am trying to understand how deadlocks are created. I've understood that by using two threads on two synchronized methods, a deadlock can be created.
Went through many examples from the net.
Can a deadlock be created with wait and notify?
Every time a thread is on wait, it will be notified. So how does this end up in a deadlock?
Illustration of an example will be helpful.
Deadlock is caused when two threads try to obtain the same, multiple locks in different order:
// T1
synchronized (A) {
synchronized (B) {
// ...
}
}
// T2
synchronized (B) {
synchronized (A) {
// ...
}
}
The only way to prevent deadlocks is to make sure that all threads obtain locks in the same order--either they all do A then B, or they all do B then A.
If you don't have multiple locks, then you don't have a deadlock. However, you can get thread starvation or other things that may look similar to deadlock.
Say thread 1 enters a synchronized block on method A and then waits. Thread 2 then attempts to enter the synchronized block on method A. Thread 1 is waiting for a notify, and thread 2 is waiting on the synchronized block. Everything is now waiting. Some other thread will have to notify the object on which thread 1 is waiting. This is just one scenario that can create a deadlock. There are all kinds of ways to do it.
A thread which is on wait will not be notified unless some code explicitly notifies it. Therefore the example you are looking for is absolutely trivial:
public static void main(String[] args) {
synchronized(String.class) {
String.class.wait();
}
}
and this hangs forever. Technically, though, it is not a deadlock, which requires two or more threads involved in a closed cycle where each thread waits for the next one to unblock it.
Something close to wait/notify deadlock:
public class Example
{
volatile boolean isNotified = false;
public synchronized void method1() {
try
{
isNotified = false;
while (!isNotified)
wait();
notifyAll();
System.out.println("Method 1");
} catch (InterruptedException e) {/*NOP*/}
}
public synchronized void method2() {
try {
isNotified = true;
while (isNotified)
wait();
notifyAll();
System.out.println("Method 2");
} catch (InterruptedException e) {/*NOP*/}
}
public static void main(String[] args)
{
Example example = new Example();
Thread thread1 = new Thread()
{
public void run()
{
example.method1();
}
};
Thread thread2 = new Thread()
{
public void run()
{
example.method2();
}
};
thread1.start();
thread2.start();
}
}

Java thread causes deadlock

I' m trying to implement some basic start, stop, pause and resume functionality that allows me the following state transitions:
stopped to running
running to stopped
running to paused
paused to running
paused to stopped (causes deadlock)
Most of this works as expected, but the last state transition is not possible, because it makes the thread freeze. Could someone please explain me why that is happening and how to prevent it? Here are the relevant parts of the code:
public class ThreadTest implements Runnable {
private volatile boolean running = false;
private volatile boolean paused = false;
private Thread thread;
public ThreadTest() {
thread = new Thread(this);
}
public void run() {
while (running) {
try {
if (paused) {
synchronized (this) {
while (paused)
wait();
}
}
}
catch (InterruptedException e) {
}
}
}
public synchronized void start() {
if(running && !thread.isAlive())
return;
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
if(!running && thread.isAlive())
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(0);
}
public synchronized void resume() {
if(paused) {
paused = false;
notify();
}
else {
return;
}
}
public synchronized void pause() {
if(!paused) {
paused = true;
}
else {
return;
}
}
}
wait(); in run method will wait forever becuase these is not notify();
When call stop, the thread is running becuase wait for ever, so thread.join() will lock.
You need call notify in stop or change wait for ever to wait(1000);
Let us see what exactly is happening here:
Let us name the threads involved here as T2 (the Thread that you explicitly instantiated and started in your code) and T1 (which invokes the start, stop methods on the T2 thread Object). T1 is probably your main thread, depending on your other unshown code.
You are getting a Deadlock because of the following sequence of events:
(Note1: This is just one possible sequence, there may be other possible sequences in this code which could also cause a deadlock)
Say we do a start(), pause() and then a stop() on the ThreadTest object as follows (say in main()):
ThreadTest t = new ThreadTest();
t.start();
t.pause();
t.stop();
After the pause() executes in T1, T2 acquired a lock on the ThreadTest object by entering the "synchronized(this)" block inside the "if(paused)" condition. (Note2: The "this" here refers NOT to the T2 thread object, but it refers to the ThreadTest object as run() is a method on the ThreadTest class.)
T2 enters into a wait() and releases the ThreadTest object lock (implicitly) just when it enters that wait() call.
When T1 enters stop(), it acquires a lock on the ThreadTest object as stop() is a synchronized method. Inside stop(), T1 calls t2.join(), and waits for T2 to complete.
But T2 is already in a wait() and has no one to wake it up !
Hence the Deadlock !
Note3: Even if we wake T2 up by specifying a timeout in the wait() call or by calling notify() (as suggested by others), it still cannot come out of the wait because it cannot re-acquire (implicitly) the lock (on ThreadTest object), as that is already held by T1 waiting in the join() !
One possible solution:
While there could be many possible solutions, can you try this one ?
In the stop() method, instead of
thread.join();
can you use:
if (!paused) {
thread.join();
} else {
thread.interrupt();
}
In the stop method, call thread.notify(); just after running = false;. (This will notify the waiting thread).
Then you must set paused = false; just before your notify call.
Remove the if (paused) block from your run method.
Change your while (paused) loop to while (paused && running). Alternatively, you could use while (paused) { wait(); if (!running) break;} depending on what control flow you want.
For good measure, add the volatile keyword to the paused and running variable declarations (to create memory fences across threads).

Categories

Resources