I have a scenario where I have one thread that loops between waiting and executing a task. However, I would like to interrupt the wait for the thread (skip the rest of the wait if you will) and continue on to doing the task.
Anyone have any ideas how this could be done?
I think what you need is implement wait()/notify() ! check it out this tutorial: http://www.java-samples.com/showtutorial.php?tutorialid=306
There are a lot of them out there! if you need a more specific case, post a bit of your code!
cheers
You could use wait() and notify(). If your thread is waiting, you'll need to resume it by calling notify() from a different thread.
This is what Thread.interrupt is for:
import java.util.Date;
public class Test {
public static void main(String [] args) {
Thread t1 = new Thread(){
public void run(){
System.out.println(new Date());
try {
Thread.sleep(10000); // sleep for 10 seconds.
} catch (InterruptedException e) {
System.out.println("Sleep interrupted");
}
System.out.println(new Date());
}
};
t1.start();
try {
Thread.sleep(2000); // sleep for 2 seconds.
} catch (InterruptedException e) {
e.printStackTrace();
}
t1.interrupt();
}
}
Thread t1 will only sleep for 2 seconds, since the main thread interrupts it. Keep in mind that this will interrupt many blocking operations such as IO.
Related
I'm curious to submit here a short example I made and hopefully have someone able to explain to me one thing: is it possible to use the wait() and notify() inside a synchronized block without having to declare threads explicitly? (AKA: not using dedicated threads).
Here's the example:
public class mutex {
private Object mutex = new Object();
public mutex(Object mutex) {
this.mutex = mutex;
}
public void step1() throws InterruptedException {
System.out.println("acquiring lock");
synchronized(mutex) {
System.out.println("got in sync block");
System.out.println("calling wait");
mutex.wait();
System.out.println("wait finished ");
}
}
public void step2() throws InterruptedException{
System.out.println("acquiring lock");
synchronized(mutex){
System.out.println("got in sync block");
System.out.println("calling notify");
mutex.notify();
System.out.println("notify called");
}
}
Those two simple step are just prints for logging and what should be happening.
The idea is to be able to call a wait() in step1 and be able to complete the call once step2 has been called with its notify().
Now, as far as I understood the whole thing, this is the right way to do what I want to do:
public void go1() {
Object mutex = new Object();
mutex m = new mutex(mutex);
Thread t1 = new Thread(()->{
try {
m.step1();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(()->{
try {
Thread.sleep(1000);
m.step2();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
}
and finally the main
public static void main(String[] args) {
Object mutex = new Object();
new mutex(mutex).go1();
//new mutex(mutex).go2();
}
The above code works and shows what I am expecting:
acquiring lock
got in sync block
calling wait
acquiring lock
got in sync block
calling notify
notify called
wait finished
I get why it works. This is what I expected to happen and how I have been taught to do this. The question comes now as I will paste the second variant of the main function I wanted to test - this one just hangs when the wait() is called.
public void go2() {
Object mutex = new Object();
mutex m = new mutex(mutex);
try {
m.step1();
Thread.sleep(1000);
m.step2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Why does this hang?
Is it because there is just one thread doing everything and it goes into waiting state after the wait() is called?
I know that when wait is called on the monitor object it should also release the lock, so why in this case the program can't get to call the step2()?
Is there a way to use the my second go() function to achieve this process or is it impossible for it to work?
TLDR just so I am making sure I can be understood: do I have to use dedicated threads to also use properly wait() and notify()? Because I seem to get deadlocks if I don't.
Thank you.
Once you call mutex#wait, the current thread is added to the wait set of object mutex. And thread will not execute any further instructions until it has been removed from mutex's wait set. That's why step2 cannot be executed by the current thread.
The current thread will be removed from the wait set and resume if other threads call mutex#notify/notifyAll. See JLS#WAIT for all situations in which the current thread can resume..
I'm not sure which one the Thread.sleep(1000) is referring to since both threads are running as well as the main thread.
I've tried searching up answers online but can't seem to find anything anywhere.
public class Practice {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
ob1.t.start();
ob2.t.start();
try {
Thread.sleep(1000);
} catch(InterruptedException a) {
System.out.println("Exception a caught");
}
}
}
A thread can not make any other thread sleep. Thread.sleep() will always make the current thread sleep. Even if you called ob1.t.sleep(), you would still be calling the static sleep(long millis) method via an instance of a Thread for the current thread you are in.
I repeat, you can not make any other thread sleep from a thread.
Yes, you are right when you say:
both threads are running as well as the main thread.
but what thread is the main method in? Is it ob1.t or ob2.t? No, it is the main thread, which means it will be the main thread that is sleeping.
In Java programs, the thread that runs the main(String[] args) function is the main thread. When you call the function Thread.sleep(long), the thread that will sleep is the thread that called the function. Take a look at this example below.
public class ThreadSleepTest {
public static void main(String[] args) {
new Thread(() -> {
System.out.println("oneSecondSleeper will sleep for 1 seconds");
try {
Thread.sleep(1000L);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}
System.out.println("oneSecondSleeper is awake now!");
}).start();
new Thread(() -> {
System.out.println("twoSecondSleeper will sleep for 2 seconds");
try {
Thread.sleep(2000L);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}
System.out.println("twoSecondSleeper is awake now!");
}).start();
System.out.println("mainThread will sleep for 3 seconds");
try {
Thread.sleep(3000L);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}
System.out.println("mainThread is awake now!");
}
}
The main thread will create two child threads that will sleep for one and two seconds respectively. After creating child threads, the main thread will sleep for 3 seconds.
This question already has answers here:
Thread.interrupt () doesn't work
(2 answers)
Closed 6 years ago.
onIncomingCall() is a overridden method from a class in third party library pjsip. This method is called when an incoming call is made using SIP. Somehow this method makes it possible for the call to be answered ONLY if the Call answering code be inside the same method or called within the same method. But I want the call to be answered when the user presses the button. I have created a call back and make the user press the button when the call comes but the call answering code is not working if its called outside of onIncomingCall() method. So I decided to put Thread.sleep(10000) in onIncomingCall() and when the user presses the button I would like to cancel this thread so that the call answering code can be executed.
I used Thread.currentThread().interrupt() but the Thread.sleep is not cancelled at all. I wrote a separate activity to test this functionality but it failed, meaning Thread.currentThread.interrupt is not working in for me at all. What is the best option to achieve this? Kindly please update me .. I am really struggling with this.
#Override
public void onIncomingCall(OnIncomingCallParam prm) {
onIncomingCallParam = prm;
try {
Thread.sleep(10000);
} catch(InterruptedException ie) {
ie.printStackTrace();
}
answerCall();
}
UPDATE:
I fixed the issue with the below approach
resetThread();
while (testThread) {
try {
Log.d(TAG,"testThread true");
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
Log.d(TAG,"Call Answering code");
private void resetThread() {
Thread newThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10000);
testThread = false;
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
});
try {
newThread.start();
} catch (Exception ie) {
ie.printStackTrace();
}
}
The problem here is related to the fact that you don't interrupt the right Thread, if you call Thread.currentThread().interrupt(), you will interrupt the current thread not the one that it is currently sleeping.
Here is a clear example to show the main idea:
// Here is the thread that will only sleep until it will be interrupted
Thread t1 = new Thread(
() -> {
try {
Thread.sleep(10_000L);
System.err.println("The Thread has not been interrupted");
} catch (InterruptedException e) {
System.out.println("The Thread has been interrupted");
}
}
);
// Start the thread
t1.start();
// Make the current thread sleep for 1 sec
Thread.sleep(1_000L);
// Try to interrupt the sleeping thread with Thread.currentThread().interrupt()
System.out.println("Trying to call Thread.currentThread().interrupt()");
Thread.currentThread().interrupt();
// Reset the flag to be able to make the current thread sleep again
Thread.interrupted();
// Make the current thread sleep for 1 sec
Thread.sleep(1_000L);
// Try to interrupt the sleeping thread with t1.interrupt()
System.out.println("Trying to call t1.interrupt()");
t1.interrupt();
Output:
Trying to call Thread.currentThread().interrupt()
Trying to call t1.interrupt()
The Thread has been interrupted
As you can see in the output, the thread is interrupted only when we call t1.interrupt(), in other words only when we interrupt the right Thread.
Maybe all calls has to be done on the same thread, which created library instance. Try using HandlerThread for posting it messages and handle those messages inside custom Handler instead of suspending thread.
I am studying the Threads in java.
I just want a simple example which explains the use of join() in Thread. I have seen this link..
Understanding join() method example
But still not able to understand the concept.
Can anybody explain me the concept of using the join() in Thread.
Any explanation retlated to this will be very helpful to me.
Thanks.
The simplest explanation I can come up is that join makes the caller thread wait for the completion of specified thread.
Say if you have a "main thread" and "thread A", if from the main thread you call A.join(), the main thread will wait until thread A finishes.
The java se manual page about concurrency should help you here: http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html
Thread.join() causes the current thread to wait for the thread you call join() on to die before it resumes execution.
Thread.join() blocks (does not return) until the thread you joined on has finished.
This is not the only way to wait for a thread to finish, but it is the most CPU-usage friendly way. Imagine if you had a loop like this (pseudocode):
while(!thread.isAlive())
{
Sleep(1);
}
This supposedly does the same thing... but, 1000 times per second, it will wake up, check the variable and go back to sleep. This means 1000 context switches (which are expensive) and the program will be slower as a result. This is called 'spinlocking' or 'busywaiting' and is frowned upon in programming as it consumes CPU for no reason.
I did some experiment and here is the result: 1. first started thread t3. 2. started t1 then 3. created t2 and t2 joinned the running thread t1.
By definition, t2 should wait for t1 to die and then it should start.
Observation: I called wait on t1, so t1 is paused but not died but I see then t2 is started why ?
public class TestThreadJoin {
public static void main(String[] args) {
final Thread t3 = new Thread(new Runnable() {
public void run() {
System.out.println("R3");
}
});
t3.start();
final Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("R1 before");
try {
perform();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("R1 after");
}
private void perform() throws InterruptedException {
synchronized(this){
wait(5000);
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println("R2");
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t2.start();
}
}
Thread t1= new Thread(new Runnable() {
public void run() {
//perform Database stuff
}
});
t1.start();
initCache();//perform other Database stuff (Can this code be executed while thread 1 is running?)
How can I make sure the initCache method is forced to wait after t1 finishes?
Don't run it in a different thread to start with?
You could call t1.join() but really, if you want to run task X and then task Y, just run them in the same thread...
If you want initCache() to only run after t1 has finished running, then why do you start t1 in the first place?
Simply execute the code in run() and then initCache().
If there's some other action happening between t1.start() and initCache(), then you could use t1.join() to wait for t1 to finish before calling initCache().
Using join()? Seriously? Did the 90's called because they want their low-level synchronization facilities back?
What about something a bit more high-level? Like a CountDownLatch?
final CountDownLatch cdl = new CountDownLatch(1);
Thread t1= new Thread(new Runnable() {
public void run() {
//perform Database stuff
cdl.countDown();
}
});
t1.start();
cdl.await();
initCache();
Can also be configured with a timeout etc.
while (t1.isAlive()) {
try {
Thread.currentThread().sleep();
}
catch (InterruptedException e) {
//check again
}
}
initCache();
That should do it. Although actually the t1.join() method is a hell of a lot simpler.