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) {
}
}
}
}
Related
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
I'm trying to understand how Java's wait and notify methods work. As per the documentation, wait() causes thread to wait for subsequent calls to notify() or notifyAll() methods but for some reason notify doesn't interrupt "waiting":
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("thread1 is started, waiting for notify()");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e.getLocalizedMessage());
}
}
System.out.println("waiting is over");
}
});
thread1.start();
// unblock thread1 in 2 seconds
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (thread1) {
thread1.notify();
}
}
You need to notify the object that is being waited on, not the thread that is waiting.
In your case the object waited on is an instance of an anonymous inner class, which is problematic because you cannot easily obtain a reference to it in order to notify it. You could solve this by extending Thread directly:
Thread thread1 = new Thread() {
#Override
public void run() {
System.out.println("thread1 is started, waiting for notify()");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e.getLocalizedMessage());
}
}
System.out.println("waiting is over");
}
};
Now the this (in synchronized (this)) refers to the thread itself, and the wait is called on the thread object too. In this case your current call to notify should be fine, since it notifies the same object (which happens in this case to be the thread that is waiting - but just to be clear, that need not be the case).
It isn't considered good practice to use an object for synchronisation that may also be used elsewhere; instances of Thread would be an example of this, and in fact the documentation specifically advises against it:
It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Also, you should correctly handle spurious wakeup; that is, wait may return because notify/notifyAll was called elsewhere or perhaps was not even called at all. As the documentation also says:
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops [...]
Therefore, your example should really use a separate variable to track whether the wakeup was intentional (due to an explicit notify) or not.
for some reason notify doesn't interrupt "waiting":
#davmac's answer is correct but for posterity, there are some other ways you can do it because extending Thread and calling wait() and notify() on the Thread object is not recommended.
The best way would be to create a lock object. Making your lock objects final is always a good pattern although here it is also necessary to use it in the inner class.
final Object lock = new Object();
Thread thread1 = new Thread(new Runnable() {
...
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
// always a good pattern
Thread.currentThread().interrupt();
System.out.println(e.getLocalizedMessage());
}
}
...
}
...
synchronized (lock) {
lock.notify();
}
// might as well wait for it to finish
thread1.join();
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.
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).
I have simple code:
public class testing {
private static Object objToSync = new Object();
public static void main(String[] args) {
String obj1 = null;
synchronized(objToSync){
System.out.println("something one");
doSomething();
System.out.println("something three ");
}
doSomething();
}
private static void doSomething() {
synchronized(objToSync){
System.out.println("something two");
}
}
I have read several things but still getting confused with this one. Why does the doSomething in the main gets called? Is it not suppose to wait till the synchronized object gets unlocked? Sorry if I am sounding stupid, i am just confused.
Is it not suppose to wait till the synchronized object gets unlocked?
The lock is held by the thread, so the fact that you're synchronizing on it twice (in the case of the first call to doSomething in main) doesn't matter, it's on the same thread. If another thread then tried to enter a synchronized block on objToSync, that other thread would wait until this thread released all of its locks.
Your code will do this:
Enter main
Get a lock for the current thread on the objToSync object
Output "something one"
Call doSomething
Get a second lock for the current thread on objToSync
Output "something two"
Release the second lock for the current thread on objToSync
Return from doSomething
Output "something three"
Release the first lock for the current thread on objToSync
Call doSomething
Acquire a new lock (for that same thread) on objToSync
Output "something two"
Release that lock
Return from doSomething
Return from main
Here's an example using two threads:
public class SyncExample {
private static Object objToSync = new Object();
public static final void main(String[] args) {
Thread second;
System.out.println("Main thread acquiring lock");
synchronized (objToSync) {
System.out.println("Main thread has lock, spawning second thread");
second = new Thread(new MyRunnable());
second.start();
System.out.println("Main thread has started second thread, sleeping a moment");
try {
Thread.currentThread().sleep(250);
}
catch (Exception e) {
}
System.out.println("Main thread releasing lock");
}
System.out.println("Main thread sleeping again");
try {
Thread.currentThread().sleep(250);
}
catch (Exception e) {
}
System.out.println("Main thread waiting for second thread to complete");
try {
second.join();
}
catch (Exception e) {
}
System.out.println("Main thread exiting");
}
static class MyRunnable implements Runnable {
public void run() {
System.out.println("Second thread running, acquiring lock");
synchronized (objToSync) {
System.out.println("Second thread has lock, sleeping a moment");
try {
Thread.currentThread().sleep(250);
}
catch (Exception e) {
}
System.out.println("Second thread releasing lock");
}
System.out.println("Second thread is done");
}
}
}
Output:
Main thread acquiring lock
Main thread has lock, spawning second thread
Main thread has started second thread, sleeping a moment
Second thread running, acquiring lock
Main thread releasing lock
Main thread sleeping again
Second thread has lock, sleeping a moment
Main thread waiting for second thread to complete
Second thread releasing lock
Second thread is done
Main thread exiting
Locks are reentrant so if some thread posses lock it can enter other synchronized blocks based on that lock. In your case you have only one thread (main) and he is doing something like this
synchronized(objToSync){
System.out.println("something one");
synchronized(objToSync){
System.out.println("something two");
}
System.out.println("something three");
}
Locks are reentrants for the same thread. That means a thread which has gained the lock of an object can access this and any other synchronized methods (or atomic statements, like here in your example) of the object. This thread will not need to gain the lock again, once it has gotten it.
Thats because your program has only 1 thread- the main thread.