Should sleeping interrupted thread reinterrupt itself if it was awaken? - java

The thread is working until it is interrupted but it is sleeping from time to time:
public void run() {
while (!Thread.interrupted()) {
//A TASK HERE
try {
Thread.sleep((long) (500 + Math.random() * 100));
} catch (InterruptedException e) {
interrupt(); //it was interrupted while it was sleeping
}
}
}
The intention is to kill the thread by interrupting it. Can I reinterrupt itself like I did or I should set a flag stop = true within the exception clause?

Catch the interruption outside the loop:
public void run() {
try {
while (true) {
//A TASK HERE
Thread.sleep((long) (500 + Math.random() * 100));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
Irrespective of where you catch the InterruptedException, it's a good idea to reinterrupt the current thread if you've not really handled it, and you can't simply throw the InterruptedException (e.g. because it's inside a method which doesn't declare that it throws InterruptedException or Exception or Throwable).
This allows callers of the run() method to know that execution was interrupted, so they can stop what they are doing too.
The main case where you may decide not to re-interrupt the thread is if you are writing some sort of threading framework (like Executors), where you reuse the previously-interrupted thread to do the next task.

Related

Cyclic barrier await method not working

I am trying to learn multithreading and was trying with a cyclic barrier. I understand that to break the barrier an await method must be called by the number of the thread mentioned while creating the barrier. I am trying to do the same but when I check if the barrier is broke my main method is going in an infinite loop.
class CyclicBarrierTrial implements Runnable{
CyclicBarrier barrier;
public CyclicBarrierTrial(CyclicBarrier barrier){
this.barrier=barrier;
}
public void run() {
System.out.println("in the run method");
try {
Thread.sleep(1000);
System.out.println("going to call awake on barrier"+ Thread.currentThread().getName());
try {
barrier.await();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("barrier broke");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println("Wake up from the Sleep"+ Thread.currentThread().getName());
}
}
public class MYCountDownLatch {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(2);
Thread t1= new Thread(new CyclicBarrierTrial((barrier)));
t1.start();
Thread t2= new Thread(new CyclicBarrierTrial((barrier)));
Thread.sleep(2000);
t2.start();
while(!barrier.isBroken())
{
System.out.println("waiting for the barrier to break "+barrier.isBroken());
}
System.out.println("MAIN THREAD finally barrier to broke ");
}
}
barrier.isBroken() indicates if barrier is in broken state, which is different than barrier is tripper.
To check this, you can try interrupting one of thread, this will raise BarrierBrokenException on other threads and barrier.isBroken() will be true.
Thread.currentThread().interrupt();
If you want to wait for all threads to complete, then you can use ExecutorService.awaitTermination or Thread.join
From documentation:
If any thread is interrupted while waiting, then all other waiting threads will throw BrokenBarrierException and the barrier is placed in the broken state.
Hope this help.

Android: execute a method and terminate it after a timeout

I need to execute a Java method for at most X seconds.
In case the method's code does not terminate after X seconds, I need my execution to continue.
I tried to use the following code (using the ExecutorService class).
private void execLoop(){
ExecutorService executor = Executors.newSingleThreadExecutor();
int iteration;
for(iteration=0;iteration<10;iteration++) {
CallableTask ct = new CallableTask();
Future<String> future = executor.submit(ct);
try {
future.get(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
class CallableTask implements Callable {
#Override
public Object call() throws Exception {
Log.d("TIME","executed!");
int t=0;
boolean c = true;
while(c){
t+=0; // infinite loop: this method will never terminate
}
return null;
}
}
What I expect from this code is to print to logcat, every 5 seconds, the string "executed!" for 10 times.
However, the execution gets stuck in the infinite loop.
First, you never shut down your executor. Add the following line as the last statement in your execLoop() method:
executor.shutdownNow();
Then, since the shutdown is accomplished by interrupting your threads, you need to make sure that your CallableTask listens to interrupts. One way is to use Thread.sleep() instead of t+=0:
while(c){
Thread.sleep(500); // This will be interrupted when you call shutdownNow()
}

Can't stop thread in Java

I'm trying to create a thread and then interrupt it. But it doesn't stop and cause exception. Can anybody explain what am I doing wrong? Thanks.
public class Test {
public static void main(String[] args) throws InterruptedException {
//Add your code here - добавь код тут
TestThread test = new TestThread();
test.start();
Thread.sleep(5000);
test.interrupt();
}
public static class TestThread extends Thread {
public void run() {
while (!this.isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
According to javadocs:
A thread interruption ignored because a thread was not alive at the
time of the interrupt will be reflected by this method returning
false.
Since you sleep the thread for 1000ms, when you call test.interrupt(), thread is asleep, almost all the times. So InterruptedException will be thrown. Therefore you should exit the loop at the catch clause.
Include a break when you catch InterruptedException to exit while loop.
while (!this.isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
break;
}
}
The internal flag gets resetted after calling interrupt.
You have to call it again in your catch of the thread.
The topic was also covered in the Java Specialists Newsletter
In my example, after I caught the InterruptedException, I used
Thread.currentThread().interrupt() to immediately interrupted the
thread again. Why is this necessary? When the exception is thrown, the
interrupted flag is cleared, so if you have nested loops, you will
cause trouble in the outer loops
Something like this should work:
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
this.interrupt();
// No need for break
}
This makes sure that the rest of the code is executed.

after catching "InterruptedException", why "Thread.currentThread().isInterrupted()"'s value is false?

as the title.
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().isInterrupted()); //print false, who reset the interrupt?
}
}
});
thread.start();
TimeUnit.SECONDS.sleep(1);
thread.interrupt();
}
after catching "InterruptedException", why "Thread.currentThread().isInterrupted()"'s value is false?
From the Javadoc for Thread.sleep (called by TimeUnit.sleep):
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
I think the intention of isInterrupted() is to allow you to detect whether a thread has been interrupted before calling something which would throw InterruptedException. If you've caught InterruptedException, it's fair to assume that the thread has been interrupted...

In Java: how can I make thread watch over another thread?

Sorry if the question is quite simple. I am a beginner.
I have to create thread that calulates something, while the first thread works the other one have to measure if the first thread calculate the function in specified time. If not, it has to throw exception. Else it returns the answer.
I'd take the java.util.concurrent components - simple example
public void myMethod() {
// select some executor strategy
ExecutorService executor = Executors.newFixedThreadPool(1);
Future f = executor.submit(new Runnable() {
#Override
public void run() {
heresTheMethodToBeExecuted();
}
});
try {
f.get(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// do something clever
} catch (ExecutionException e) {
// do something clever
} catch (TimeoutException e) {
// do something clever
}
}
Have your thread notify a synchronization object when it is done and have your other thread wait x number of milliseconds for it to finish.
public class Main {
private static final Object mThreadLock = new Object();
static class DoTaskThread extends Thread {
public void run() {
try {
int wait = new Random().nextInt(10000);
System.out.println("Waiting " + wait + " ms");
Thread.sleep(wait);
} catch (InterruptedException ex) {
}
synchronized (mThreadLock) {
mThreadLock.notifyAll();
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
synchronized (mThreadLock) {
DoTaskThread thread = new DoTaskThread();
thread.start();
try {
// Only wait 2 seconds for the thread to finish
mThreadLock.wait(2000);
} catch (InterruptedException ex) {
}
if (thread.isAlive()) {
throw new RuntimeException("thread took too long");
} else {
System.out.println("Thread finished in time");
}
}
}
}
join is a lot simpler than using a lock.
join (millis)
Waits at most millis milliseconds
for this thread to die. A timeout of 0
means to wait forever.
Example code:
Thread calcThread = new Thread(new Runnable(){
#Override
public void run() {
//some calculation
}
});
calcThread.start();
//wait at most 2secs for the calcThread to finish.
calcThread.join(2000);
//throw an exception if the calcThread hasn't completed.
if(calcThread.isAlive()){
throw new SomeException("calcThread is still running!");
}
Have a look at http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination(long,%20java.util.concurrent.TimeUnit) which allows you to handle this without dealing with thread synchronization yourself.

Categories

Resources