I am new for multi-threading.currently i am learning lock and notify and synchronize block . i created a small program to check how wait and notify working with synchronize block , if i will not create any thread(i supposed main thread will get the lock). Below is the code for better understanding .
public class Problem1
{
public void waitForSignal() throws InterruptedException
{
Object obj=new Object();
synchronized (obj) {
obj.wait();
obj.notify();
}
}
public static void main(String args[]) throws InterruptedException
{
Problem1 pb=new Problem1();
pb.waitForSignal();
System.out.println("hello");//controll not come here
}
}
if i run the above program it will stuck. and control neither goes to notify() and nor it will exit the synchronize block. why code behave like this.
i tried to search on google and i found the below statement
wait( ) tells the calling thread to give up the monitor and go to
sleep until some other thread enters the same monitor and calls
notify( ).
what i understand from above statement that , for correct execution of my the program i have to create another thread, that will enter in the same monitor and interrupt the execution of the current lock holding thread. Please make me correct if i am wrong.
Please me to correct above code , so it will work fine without Stuck.
When you call wait, some other thread will have to acquire the lock on obj and call notify or notifyAll to signal the waiting thread to proceed. The easiest way to understand is in the context of the Consumer/Producer problem, and Oracle has a pretty good tutorial about that.
Thread interruption is something entirely different. It is a request for the interrupted thread to check its interrupted status and terminate processing. Brian Goetz has a great article about this in the context of properly handling InterruptedException.
Related
I have a quick question. I basically have a synchronized method which does some task when called upon so.
I use multi threads and sometimes, when the task is being executed by one thread, the thread hangs causing the synchronized method to be in blocked state indefinitely. This doesn't allow the next process to access the block.
Is there a way where I can set a timer, where after a said time ( say 60 seconds) the synchronized method gets released so other threads can still continue and not get blocked?
If there is a way, can someone please put up a sample code.
Thanks in advance!
You can use a lock instead of synchronized keyword
To be able to forcefully unlock a lock owned by another thread, you can use following implementation https://stackoverflow.com/a/16492269/5313017
The method would be like following
public void synchronizedMethod() {
if(!lock.tryLock(10, TimeUnit.SECONDS)){
lock.forceUnlock();
}
doStuff();
lock.unlock();
}
I am curious whether it is possible to pause a thread t in Java and allow another thread to resume it later, by having t run the following pause code:
while(true) {
try {
synchronized(t) {
t.wait();
}
} catch(InterruptedException e) {
break;
}
}
And then resuming the thread t by calling .interrupt() on it. However, I have read about spurious wake-ups, and so I wondered whether my code can fail, in the sense of exiting the while-loop despite no other thread calling .interrupt() on it. While this answer and this answer state that there are no spurious interrupts, and hence my code will never fail, the Java docs does not seem to address this. My question probably boils down to whether InterruptedException is ever thrown without the thread being interrupted by .interrupt(). Is there any official source or documentation that confirms this?
Summary
So, although technically this works, there are numerous reasons why this should not be done. Oracle's documentation states that interruption should only be utilized for cancellations. But if you were to do this, it will clear the interrupt status and the previously waiting thread will receive an InterruptedException.
Alternative
Lets step through a brief, simplified example.
Object obj = new Object;
synchronized (obj) {
while(condition) {
obj.wait();
}
}
A thread here will obtain the monitor.
The thread will begin to wait via wait(), and release the monitor. Always utilize wait() inside a conditional because threads are subject to get spurious wake-ups from wait(). At this point, you have achieved forcing a thread to wait.
Lets investigate how we go about returning the thread to work.
synchronized(obj) {
obj.notify();
}
The notify() will wake up the first waiting thread on the monitor. Now, if you want all waiting threads to wake up, utilize notifyAll() instead. This is the intended purpose and functionality of wait()/notify() and thus should be utilized over wait()/interrupt(). For an additional example, see this article.
I am trying to understand the concept of synchronized blocks in java.
As of the documents that I have read, I understood that if we acquire
a lock ( synchronized block using an instance variable ) then we
cannot acquire a synchronized lock on same object in that class. But
when I tried practically using the following snippet I found that my
understanding is going wrong.
I.e I am able to acquire lock
(synchronized block on same instance variable) in two different
methods at the same time. When the thread is started it will go to run
method and wait indefinitely and will not come out of the synchronized
block. At the same time if I call the stop method using the same
thread it goes into the synchronized block and executes notify
statement. I searched in the Java doc but I couldn't find any.
This is the code snippet:
public class MyClass extends Thread
{
private Object lock = new Object();
public void run()
{
synchronized(lock)
{
lock.wait()
}
//other code
}
public void stop()
{
synchronized(lock)
{
lock.notify()
}
//other code
}
}
Here is the code snippet of how i am managing the MyClass thread:
public class MyClassAdmin
{
MyClass _myclass;
public MyClassAdmin()
{
_myclass=new MyClass();
_myclass.start();
}
public void stop()
{
_myclass.stop();
}
public static void main(String args[])
{
MyClassAdmin _myclassAdmin=new MyClassAdmin();
_myclassAdmin.stop();
}
}
According to my understanding when the thread is started it will acquire lock on 'lock' object (synchronized block in run method of MyClass). When i call the stop method it should wait indefinitely until the run method comes out of the synchronized block (which will never happen in this case). But when i executed, call to stop method acquired lock on the 'lock' object and notified the object which resulted in shutdown of the thread.
Both of your methods use the same lock. If your MyClass thread happens to start waiting before the main thread can call the stop method, your stop method can still proceed, because the waiting thread lets go of the lock. Once a thread enters the wait method it releases the lock before it goes dormant, and doesn't re-acquire the lock until it exits the wait method.
This is the relevant API doc for Object#wait, the second paragraph covers what I described above about how wait releases the lock. Pay attention to the part where it says you have to call this method in a loop, otherwise you have an order-dependency bug that can cause the waiting thread to hang when the notification arrives in the main thread before the other thread can start waiting.
public final void wait()
throws InterruptedException
Causes the current thread to wait until another thread invokes the
notify() method or the notifyAll() method for this object. In other
words, this method behaves exactly as if it simply performs the call
wait(0).
The current thread must own this object's monitor. The thread releases
ownership of this monitor and waits until another thread notifies
threads waiting on this object's monitor to wake up either through a
call to the notify method or the notifyAll method. The thread then
waits until it can re-obtain ownership of the monitor and resumes
execution.
As in the one argument version, interrupts and spurious wakeups are
possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
This method should only be called by a thread that is the owner of
this object's monitor. See the notify method for a description of the
ways in which a thread can become the owner of a monitor.
Understood this is a toy example, but subclassing Thread and overriding Thread methods is confusing. One of the reasons for using Runnable instead of Thread is that there's no opportunity to cause problems by mistakenly overriding Thread methods.
This is multithreaded and it may wait forever may not.
In your case you were lucky that _myclassAdmin.stop(); were executed after MyClass has started executing and executed wait();
I ran the program after changing the method stop() name to stop1() it were waiting forever.
To get consistent behavior do one thing, put a 1 sec sleep between two method call in main like:
MyClassAdmin _myclassAdmin=new MyClassAdmin();
Thread.sleep(1)
_myclassAdmin.stop();
Now, the execution will always halt.
Also, when a thread calls wait() it releases the monitor associated with it, so any other thread can aquire that lock and issue a notify() / notifyAll() to wake up waiting threads. This is expect
The following code creates a new costum Thread and waits for the thread to end and only then the main thread gets active again.
I don't quite understand how it works. Why doesn't mythread.wait(); get called immediatlly?
Why not using Thread.join() instead?
public static void main(String[] args) {
Thread mythread = new MyThread("hello");
mythread.start();
synchronized (mythread) {
try {
mythread.wait();
} catch (InterruptedException e) {
}
}
}
When a thread has finished running, it calls notifyAll() on itself. That's how Thread.join() is implemented: it waits on the thread. So, since your main thread waits on the thread, as soon as it finishes running, the main thread is notified, and can continue executing.
You're violating a documented rule: you should never wait on a Thread object. You also violate another one: wait() should always be called inside a loop checking for a condition.
The way it is working is that when myThread terminates it calls notifyAll() which wakes up your myThead.wait(). Check the java documentation for the Thread.join() method where it references its implementation.
See Java synchronization is doing auto notify on exit ? Is this expected?
Why not use join instead? I think you should. Less code you have to write. It's really not much more than what you've implemented here and other people reading your code are probably more familiar with using that call to wait on thread exit.
Running will start from the main method and if in some method i am using this.wait() without synchronized block, it will throw illegalStateMonitorException.
If there is only one thread why can't it wait, why should we use locking here. Thread is not going to perform any other task also. It could have waited there.
I am not understanding why locking is needed if there is single thread.
public class waitSleepCheck extends Thread{
public void method() throws InterruptedException ,IllegalMonitorStateException{
this.wait(1000);
}
public static void main(String args[]) throws InterruptedException{
waitSleepCheck object = new waitSleepCheck();
object.method();
}
}
Object.wait isn't "wait this long". It's "wait for some other thread to do something". The forms that take arguments are "wait for some other thread to do something, but get bored and stop after this long". You need to hold the object's lock to ensure proper synchronization with the thread that will notify you that the thing you're waiting for got done. It doesn't make sense to use the method in a single-threaded context.
If you just want to wait for a certain length of time, Thread.sleep is the method you want.
Because you have called a method that "causes the current thread to wait until another thread ...", and so isn't appropriate in the first place for a single-threaded application.
synch(lockObj) {Object.wait()} means that you wait until another thread signal you (see Object.notify()). In the underlying system, these methods are translated to wait(lockObj); and pulseevent(target); Which handles do yo think JVM will sumbit to them? If you do not specify the lock object then java has no idea which sync object (aka lock) you want to communicate over.