I'm developing an Android app.
I have two threads. The first one has to wait the second one.
I have this code on the first thread run method:
#Override
public void run() {
synchronized (this.secondThread) {
this.secondThread.wait();
}
[...]
}
And on my second thread:
#Override
public void run() {
synchronized (MyClass.myLock) {
try {
// Do something important here
}
catch (Exception ex)
{
// manage exception
return;
}
finally {
// do something...
}
}
synchronized (this) {
this.notify();
}
[...]
}
As you can see, there is a return inside catch block.
With this code, will first thread get notified if an exception occurs on the second thread?
will first thread get notified if an exception occurs on the second
thread?
Answer is no. Unless you explicitly notify() in catch block before returning, the other thread will not wake up
Answer is no. In order to get both notify the has to be synchronized on the same object. this can be different. If you want all the thread waiting on a object to be notify you havo to call notifyAll() instead of notify(). The notifyAll() should be put inside the finally block. Infact despite the return the finally block is alway executed
The notify() should be inside the finally block if you want it to work unconditionally, but you should really be using Thread.join() instead of wait(): then the thread being waited on doesn't have to do anything at all.
Answer is no. Unless you explicitly notify() in catch block before returning, the other thread will not wake up, You have to Al possible exceptions and in every case notify to your first thread, make sure that your first thread input is not dependent on second thread output otherwise you may phase some other problem in thread 1.
Related
I am currently running a Thread from a Service to do some background work.
Now there is the possibility that the Thread crashes or I want to
interrupt the thread from the Service. So how am I supposed to:
stop the Thread realiable, (hard)
catch exceptions and call the Service about the crash
handle InterruptedException if interrupted while sleep()
is Thread.isInterrupted a good way to detect if the Thread stopped?
What I have done so far is the following:
#Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
doMyBackgroundWork();
sleep();
}
}catch(Exception e){
ExceptionHandler.logAndSendException(e);
Thread.currentThread().interrupt();
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
LOG.i("Thread stops now.");
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
//what to do here? it can happen because I stopped it myself
}
}
So at first I am running my Thread until it gets interrupted.
If any exception occurs, I want to start a new Thread, therefore
my Service implements a listener interface and I call it, once an
Exception is thrown. I know that catching everything is discouraged,
but I need to know if the Thread stops, without polling Thread.isAlive()
all the time.
Additionally to my four questions above:
is my code reliable and does what I need?
is it ok to call interrupt on the Thread itself?
Thanks!
You are not actually interrupting your own thread because the catch block is outside of the while loop. Therefore, any exception would stop execution immediately.
Interruption is essentially just a request (usually from another thread) to stop doing what you are doing. The thread is free to ignore it and keep doing what it is doing. Normally you have to throw an exception in response to an interrupt, or stop execution some other way such as just breaking from the loop (you need this around the //what to do here? comment). It so happens that some library methods are "responsive to interruption" meaning they will throw an exception if the thread is ever interrupted, such as Thread.sleep(), which you will most likely have in your sleep call.
I recommend picking Java Concurrency In Practice. Among the excellent concurrency material, there is a chapter on interrupts which is very helpful.
EDIT:
I would remove the code where you interrupt your own thread. You will also need to rethrow the InterruptedException as a runtime exception to get out of the execution loop. Usually people will create a new Exception that extends RuntimeException that is something like MyInterruptedException. You can then add it to the catch block around your loop so that you know when the thread was interrupted vs execution failed.
As a general example you can do something like this:
public void run() {
try {
while (true) {
// check for interrupts in the loop, or somewhere in the work method
if (Thread.interrupted()) {
throw new MyInterruptedException("Important thread interrupted.");
}
doMyBackgroundWork();
sleep();
}
}
catch(Exception e){
ExceptionHandler.logAndSendException(e);
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
catch(MyInterruptedException i) {
LOG.i("Execution stopping because of interrupt.");
}
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
throw new MyInterrptedException(e);
}
}
we have a nice and effective method called stop()(Thread.stop(void):void) which is deprecated, but it works and it's lovely.
Note that stop() throws ThreadDeath at the target thread which is not an exception(and it could any other throwable too), but an Error, so your code will not catch any signal about this.
public void run() {
try {
while (<<using_a_volatile_bool_type_is_better>>) {
...
}
}catch(Throwable t){/**/}/*use throwable instead of exception.*/}
}
Beside dear friend stop() we also have pause() method too, and it really pauses the target thread.
Not just one solution out there, but if it's really critical to keep thread run and run the emergency(or itself) just after any crash, you may run it as a separately app/process, plus get progress status(if any) that ensures you the target thread/app is not freezed(blocked,...)
I have this piece of code:
Profile a = randomProfile();
Thread workerA = new Thread(new Downloader(a));
workerA.start();
Profile b = randomProfile();
Thread workerB = new Thread(new Downloader(b));
workerB.start();
synchronized (workerA) {
try {
workerA.wait();
} catch (InterruptedException e) {
System.out.println("Error on background thread!");
System.exit(1);
}
}
synchronized (workerB) {
try {
workerB.wait();
} catch (InterruptedException e) {
System.out.println("Error on background thread!");
System.exit(1);
}
}
And a Downloader class which implements the Runnable interface, and its run() method looks like:
#Override
public void run() {
synchronized (this) {
//work...
notify();
}
}
Now this is working as intented, sometimes. Most of the time though, it seems to get stuck in the second synchronized block (it always gets through the first one).
Am I doing something wrong?
Also do I have some conceptual error, e.g. this implementation doesn't give me any advantage over a single thread?
The wait() is invoked on the Thread objects but the notify() is invoked on the Downloader objects.
The background threads should therefore run without a problem (although completely unsynchronized), and the main thread should always block to infinity in the first synchronized block because there's no-one to wake it up.
Where this case is special is that you invoked wait() on the Thread objects themselves, which is discouraged (and by this I really mean: forbidden). When a thread terminates, it invokes notifyAll() on itself, so when workerA finishes, you get out of the first synchronized block. But by the time the second synchronized block is reached, workerB is already finished, so the second wait() will never end.
Whether there is a conceptual error depends on what you were trying to achieve. From the code it looks very much like what you tried to do is join() the background threads.
Pretty much all resources I've found on synchronized blocks use this or a member of the class as a lock object. I'm interested in finding out why I can't get synchronized blocks to work when the lock object is a (static) member of another class. Here's my code to illustrate the problem:
public class Test {
public static void main(String[] args) {
Thread thread1 = new FirstThread();
Thread thread2 = new SecondThread();
thread1.start();
thread2.start();
}
}
class FirstThread extends Thread {
#Override
public void run() {
synchronized (Lock.lock) {
System.out.println("First thread entered block");
try {
Lock.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("First thread exited block");
}
}
class SecondThread extends Thread {
#Override
public void run() {
try {
Thread.sleep(1000); //just making sure second thread enters synch block after first thread
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (Lock.lock) {
System.out.println("Second thread entered block");
Lock.lock.notifyAll();
}
System.out.println("Second thread exited block");
}
}
class Lock {
public static Object lock = new Object();
}
My understanding is that the second thread should not be able to enter the synchronized block until the first thread exits, since they are synchronized on the same object. Thus I was expecting the program to hang (deadlock?) after "First thread entered block", since the second thread can't enter the block and the first thread will be stuck waiting for a notification. But instead I got the following output:
First thread entered block
Second thread entered block
Second thread exited block
First thread exited block
Clearly the second thread enters the synchronized block before the first thread has left it's block. Can someone explain what I'm missing?
I thought the purpose of synchronized blocks was to prevent exactly this. Is it because the lock object is a member of another class?
first thread Lock.lock.wait() relinquish the lock on the synchronized object so other thread can enter the critical path and wake up the waiters.
note that sleep(), instead, does not.
Difference between wait() and sleep()
Quote from the javadoc of Object.wait():
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.
If that was not the case, waiting would systematically cause a deadlock, since no thread would ever be able to enter the synchronized section needed to call notify() or notifyAll(), making wait and notify completely useless.
When you call lock.wait you "release ownership of this monitor". This allows thread 2 to enter the synchronized block.
I am trying to interrupt a normally running thread (which is not in sleep() or wait() state) .
while going through in net i got to know interrupting a normally running thread will just set the flag true and continue the process.
Code snippet is
one.java
......
......
actionperformedmethod {
if (actionCmd.equals("cancel")) {
try {
r1.stop(); // to two.java
} catch (InterruptedException ex) {
....
....
}
}
}
in two.java
.....
.....
stop method() throws InterruptedException{
if(!(t.isInterrupted())){
t.interrupt();
throw new InterruptedException();
}
}
from two.java when i throw InterruptedException i can able to get the exception block at one.java , but how do i stop the thread after that because even after that thread seems to continue the normal process.
Am new to thread concepts please help..
The interrupt() method is co-operative rather than pre-emptive - the background task needs to actively check Thread.interrupted() at suitable intervals, and take action to shut itself down cleanly.
public void run() {
openSomeResources();
try {
while(notFinished) {
if(Thread.interrupted()) return;
doSomeStuff();
}
} finally {
closeTheResources();
}
}
In this example if the thread is interrupted in the middle of doSomeStuff() then it will complete the current "iteration" before responding to the interruption. Getting the correct balance between responding promptly to an interrupt on the one hand, and responding only at a safe point in the execution on the other hand, is something that is inherently specific to the particular task - there is no one-size-fits-all answer.
Note however that any blocking method that throws an InterruptedException will reset the interrupt flag when this exception is thrown. Therefore in order for this sort of checking to work you must re-interrupt yourself whenever you receive an InterruptedException
try {
Thread.sleep(3000);
} catch(InterruptedException e) {
// we were interrupted - set the flag so the next interrupted() check will
// work correctly.
Thread.currentThread().interrupt();
}
Interrupt will not stop the thread. it just sets the flag to true to signal the thread to stop the execution soon.
to stop the execution
add global variable as
private volatile boolean exit = false;
and
you add one method in your 2nd class
public void requestExit(){
exit = true;
}
inside run () of your thread do something like this
if (exit == true){
return;
}
whenever you want to call just call this method requestExit() from your main() or wherever you want to stop
this is the best way to stop the thread.. using stop() on thread is dangerous as it does not clear any resources and its not advisable to use even by oracle hence deprecated.
let me know for any issues
Threads are only running whilst their run() method is on the stack so usually people put a while(true) inside the run method, all you need to do in you thread to stop it is to return somewhere in the run method or break the loop then as soon as the run() method is no longer running the thread has been stopped.
I have a method which uses CyclicBarrier as shown below:
public void getMessage(Message obj){
CyclicBarrier barrier = new CyclicBarrier(1, new Runnable() {
#Override
public void run() {
synchronized(obj){
System.out.println("--The End --");
}
}
});
executor.execute(new Runnable() {
#Override
public void run() {
synchronized(obj){
//Perform some routine with message object
}
try {
barrier.wait();//java.lang.IllegalMonitorStateException thrown on this line
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
At the point where i wait for the routine to finish executing, i get:
Exception in thread "pool-2-thread-3"
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
Do anyone knows what I am doing wrong here?
In order to call wait() on any object, the current thread has to own its monitor. You're calling barrier.wait() without any synchronized(barrier).
However, you may have meant to use the await() method (on CyclicBarrier) instead of wait(). It's hard to say, as it's not clear what you're trying to achieve.
yeah, you need to gain the monittor of barrier like so:
synchhronized(barrier){
try {
barrier.wait();//java.lang.IllegalMonitorStateException not thrown on this line
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Maybe you did want to use await() instead that wait()?
wait is used to block a thread over a specific object and it is a feature of every object, but in your case you are calling it without taking the monitor of it. You should call wait from inside the same obect or use a synchronized block over barrier itself.
You need to acquire lock before using the barrier object.
Regards,
Dheeraj Joshi
The cyclicBarrier is not intended to be used as you do here : participating threads are expected to call the blocking "await()" method.
As a side note, a CyclicBarrier with a count of 1 is totally useless : its intent is to allow a certain number of threads (the barrier count) to wait for each other before continuing.
Maybe you should consider changing your whole algorithm, especially if you're not sure about how concurrency stuff works.