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.
Related
I have a question about threads in Java.
I have the following code:
public static void main(String[] args) {
Runnable r = () -> {
while (!Thread.interrupted()) {
System.out.println("Hola");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("interrupted");
break;
}
}
};
Thread t = new Thread(r);
t.start();
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
t.interrupt();
}
Why if I introduce an interrupt does it still enter the loop? (without break).
I understand the operation of the thread when there is an exception.
Whenever the sleep method detects an interruption it resets the interrupt flag before throwing an InterruptedException. So if you don't use break then the interrupt flag is set to false by the time the exception is caught and the while loop test never detects the interruption.
The recommended practice is to add a line to your catch block like this
Thread.currentThread.interrupt();
if you want to keep the interrupt status.
It's not a problem here but be aware that Thread.interrupted() resets the interrupt flag. It's a convenience method used by some JDK code so that resetting the interrupt flag and throwing the exception takes less code.
This question already has answers here:
How to stop a java thread gracefully?
(6 answers)
Closed 9 years ago.
I create a thread in Java inside a button to print a simple message but I cannot stop it.
Thread a = new Thread();
a.start();
while(true){
try{
Thread.sleep(2000);
System.out.println("code");
}catch(Exception e){
}
}
when I click on it, itvstarts to print the code, but it seems to be blocked (the button). I would like to know. how can I stop the thread? And if I stop it, would be the button available again?.
I´m using netbeans 7.3, thanks.
while(true){
}
starts an infinite loop due to which all the other operations are blocked.
Remove that
Use interrupt(). Then handle the InterruptedException
The thread you are starting is not doing anything. It starts when you call a.start() and instantly terminates, because there is no code for this thread to run. Following this, the same thread that started the new one, and that is processing the click event, enters an infinite loop, so your user interface is completely blocked.
You need to give some code for the new thread to execute. To do so, you either pass the thread a Runnable or you override the thread's run() method. For example, to give it a Runnable containing the loop that prints every 2 seconds, you could do:
final Thread a = new Thread(new Runnable() {
#Override public void run() {
while (true) {
try {
Thread.sleep(2000);
System.out.println("code");
} catch (InterruptedException e) {
break;
}
}
}
};
a.start();
After that, if you ever want to stop that thread, you'd need to save a reference to the thread a in a field or something, and then call a.interrupt(). This will cause sleep to throw an InterruptedException, which will be caught and will execute break, which terminates the infinite loop and allows the thread to reach the end of the run method, which terminates the thread.
For example:
private Thread a = null;
... click handler on start button ... {
if (a == null) {
a = new Thread(new Runnable() {
#Override public void run() {
while (true) {
try {
Thread.sleep(2000);
System.out.println("code");
} catch (InterruptedException e) {
break;
}
}
}
};
a.start();
}
}
... click handler on "stop" button ... {
if (a != null) {
a.interrupt();
a = null;
}
}
You do not stop a thread in Java, you send an interrupt() signal.
The Thread may, or may no catch the signal. If it is waiting, or sleeping or joining (wait(), sleep() or join()) has been called on it), an InterruptedException will be raised.
The Thread (in its while loop) can test whether it has been interrupted by calling the isInterrupted() method and then decide to commit suicide (e.g. exit the loop).
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.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Does a finally block always run?
I learned that the finally clause of a try catch statement, executes always. But some guy said to me that it is possible to avoid executing it(removing it is not an option).
-Does someone how is that possible?
-Also i am curious in knowing why would someone want to avoid to execute it?
Kill it with an uncaught exception within the finally block, or kill the overall JVM (which kills the thread, among other things).
There is no good reason to stop the execution of a finally block except poor design. If it's not supposed to run every time, then don't put it in a finally block.
Using the below test code, I run two different scenarios to see what happens when killing the Thread:
Start the Thread and sleep the main thread for 2 seconds. Within the Thread, pretty much immediately enter the finally block and then sleep for 5 seconds. Once the main thread is finished waiting, kill the Thread using stop.
Start the Thread and sleep 2 seconds. Within the Thread, sleep 5 seconds before entering the finally block and then sleep some more within the finally to give it a chance to be killed.
In the first case, the result is that the finally block stops executing.
In the second case, the result is that the finally block executes completely, and on the Thread that was stopped no less.
Output (note the name of the current thread added for all output):
thread-starting [main]
trying [Thread-0]
catching [Thread-0]
finally-sleeping [Thread-0]
thread-stopped [main]
[main]
thread-starting [main]
trying-sleeping [Thread-1]
thread-stopped [main]
finally-sleeping [Thread-1]
finally-done [Thread-1]
Code:
public class Main
{
public static void main(String[] args)
{
testThread(new TestRunnable());
println("");
testThread(new TestRunnable2());
}
private static void testThread(Runnable runnable)
{
Thread testFinally = new Thread(runnable);
println("thread-starting");
testFinally.start();
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
println("main-interrupted...");
}
testFinally.stop();
println("thread-stopped");
}
private static class TestRunnable implements Runnable
{
#Override
public void run()
{
try
{
println("trying");
throw new IllegalStateException("catching");
}
catch (RuntimeException e)
{
println(e.getMessage());
}
finally
{
println("finally-sleeping");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
println("finally-interrupted");
}
println("finally-done");
}
}
}
private static class TestRunnable2 implements Runnable
{
#Override
public void run()
{
try
{
println("trying-sleeping");
Thread.sleep(5000);
}
catch (InterruptedException e)
{
println("trying-interrupted");
}
finally
{
println("finally-sleeping");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
println("finally-interrupted");
}
println("finally-done");
}
}
}
private static void println(String line)
{
System.out.printf("%s [%s]%n", line, Thread.currentThread().getName());
System.out.flush();
}
}
-Does someone how is that possible?
System.exit(0);
-Also i am curious in knowing why would someone want to avoid to execute it?
To answer questions like these and appear smart. ;)
BTW, Thread.stop() doesn't prevent finally being called.
Thread t = new Thread() {
#Override
public void run() {
try {
System.out.println("Thread start");
Thread.sleep(1000);
System.out.println("Thread end");
} catch (InterruptedException ie) {
System.out.println("Thread Interrupted");
} catch (Error e) {
System.out.println("Thread threw an error " + e);
throw e;
} finally {
System.out.println("Thread finally");
}
}
};
t.start();
t.join(100);
t.stop();
prints
Thread start
Thread threw an error java.lang.ThreadDeath
Thread finally
There's no way of avoiding it, unless something external happens such as the Java Virtual Machine shutting down.
As a general rule you should always assume that a finally block will run. The whole point of it is to ensure that it runs regardless of what happens in the try block - there should be no reason to avoid it!
To your first question i think the only way that comes to my mind is by creating an infinite loop or something.(But it makes no sense at all)
try{
while(true);
}
catch(Exception e) {
}
finally {
//..
}
To your second question, i don't really know why would someone want to do something like that
See this link: https://stackoverflow.com/posts/6228601/edit
I can't think of a good reason that you would want to avoid a finally block. If you really don't want to use this feature, then just don't implement a finally block (at your own risk however).
Killing the JVM would do it, but that's not really an acceptible solution for any production code.
Why is removing a finally block not an option?
Thread currentThread=Thread.currentThread();
public void run()
{
while(!shutdown)
{
try
{
System.out.println(currentThread.isAlive());
Thread.interrupted();
System.out.println(currentThread.isAlive());
if(currentThread.isAlive()==false)
{
shutdown=true;
}
}
catch(Exception e)
{
currentThread.interrupt();
}
}
}
});
thread.start();
The alternative to calling stop is to use interrupt to signal to the thread that you want it to finish what it's doing. (This assumes the thread you want to stop is well-behaved, if it ignores InterruptedExceptions by eating them immediately after they are thrown and doesn't check the interrupted status then you are back to using stop().)
Here's some code I wrote as an answer to a threading question here, it's an example of how thread interruption works:
public class HelloWorld {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
System.out.println("Hello World!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
thread.start();
System.out.println("press enter to quit");
System.in.read();
thread.interrupt();
}
}
Some things to be aware of:
Interrupting causes sleep() and wait() to immediately throw, otherwise you are stuck waiting for the sleep time to pass.
Note that there is no need for a separate boolean flag.
The thread being stopped cooperates by checking the interrupted status and catching InterruptedExceptions outside the while loop (using it to exit the loop). Interruption is one place where it's ok to use an exception for flow control, that is the whole point of it.
Setting interrupt on the current thread in the catch block is technically best-practice but is overkill for this example, because there is nothing else that needs the interrupt flag set.
Some observations about the posted code:
The posted example is incomplete, but putting a reference to the current thread in an instance variable seems like a bad idea. It will get initialized to whatever thread is creating the object, not to the thread executing the run method. If the same Runnable instance is executed on more than one thread then the instance variable won't reflect the right thread most of the time.
The check for whether the thread is alive is necessarily always going to result in true (unless there's an error where the currentThread instance variable is referencing the wrong thread), Thread#isAlive is false only after the thread has finished executing, it doesn't return false just because it's been interrupted.
Calling Thread#interrupted will result in clearing the interrupt flag, and makes no sense here, especially since the return value is discarded. The point of calling Thread#interrupted is to test the state of the interrupted flag and then clear it, it's a convenience method used by things that throw InterruptedException.
Typically, a thread is terminated when it's interrupted. So, why not use the native boolean? Try isInterrupted():
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
}});
t.start();
// Sleep a second, and then interrupt
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.interrupt();
Good way to do it would be to use a boolean flag to signal the thread.
class MyRunnable implements Runnable {
public volatile boolean stopThread = false;
public void run() {
while(!stopThread) {
// Thread code here
}
}
}
Create a MyRunnable instance called myrunnable, wrap it in a new Thread instance and start the instance. When you want to flag the thread to stop, set myrunnable.stopThread = true. This way, it doesn't get stopped in the middle of something, only where we expect it to get stopped.