When I place #timeout above the test then it fails when runs too long.
Hot to mark it as passed instead?
Based on the documentation of #timeout, #timeout is made to fail the test if the method doesn't meet to finish its operation within the required time. Hence, you cannot use #timeout to mark it as passed if the method is taking longer than it's expected.
Otherwise, based on another question, to achieve your purpose, you can use Java Thread and sleep() method to check whether the Thread.isAlive() after some period of time.
Example:
...
// Create and start the task thread.
Thread taskThread = new Thread(){
public void run(){
System.out.println("Thread Running");
}
}
taskThread.start( );
// Wait 3 seconds.
sleep(3000);
boolean status = false;
// If after waiting 3 seconds the task is still running, stop it.
if (taskThread.isAlive( )) {
taskThread.interrupt( );
} else {
status = true;
}
assertTrue(status);
...
Related
I have 5 threads (5 instances of one Runnable class) starting approximately at the same time (using CyclicBarrier) and I need to stop them all as soon as one of them finished.
Currently, I have a static volatile boolean field threadsOver that I'm setting to true at the end of doSomething(), the method that run() is calling.
private static final CyclicBarrier barrier = new CyclicBarrier(5);
private static volatile boolean threadsOver;
#Override
public void run() {
try {
/* waiting for all threads to have been initialised,
so as to start them at the same time */
barrier.await();
doSomething();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
public void doSomething() {
// while something AND if the threads are not over yet
while (someCondition && !threadsOver) {
// some lines of code
}
// if the threads are not over yet, it means I'm the first one to finish
if (!threadsOver) {
// so I'm telling the other threads to stop
threadsOver = true;
}
}
The problem with that code is that the code in doSomething() is executing too fast and as a result, the threads that finish after the first one are already over by the time that the first thread noticed them.
I tried adding some delay in doSomething() using Thread.sleep(), which reduced the number of threads which finished even after the first one, but there are still some times where 2 or 3 threads will finish execution completely.
How could I make sure that when one thread is finished, all of the others don't execute all the way to the end?
First where I copied code snippets from: https://www.baeldung.com/java-executor-service-tutorial .
As you have 5 tasks of which every one can produce the result, I prefer Callable, but Runnable with a side effect is handled likewise.
The almost simultaneous start, the Future task aspect, and picking the first result can be done by invokeAny below:
Callable<Integer> callable1 = () -> {
return 1*2*3*5*7/5;
};
List<Callable<Integer>> callables = List.of(callable1, callable2, ...);
ExecutorService executorService = new ThreadPoolExecutor(5);
Integer results = executorService.invokeAny(callables);
executorService.shutDown();
invokeAny() assigns a collection of tasks to an ExecutorService, causing each to run, and returns the result of a successful execution of one task (if there was a successful execution).
Over here I'm trying to join a thread after it has been terminated, the code is working fine, but my question doesn't it should throw some error messageor any info?
public class MultiThreadJoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new MultiThreadJoinTest());
a.start();
Thread.sleep(5000);
System.out.println("Begin");
System.out.println("End");
a.join();
}
public void run() {
System.out.println("Run");
}
}
If you look at the source code of Thread::join you will notice that it calls Thread::join(timeout) method. And looking at the source code of this method we can see that it checks status of the thread in a loop by calling Thread::isAlive :
...
if (millis == 0 L) {
while (this.isAlive()) {
this.wait(0 L);
}
} else {
while (this.isAlive()) {
long delay = millis - now;
if (delay <= 0 L) {
break;
}
this.wait(delay);
now = System.currentTimeMillis() - base;
}
}
...
so if a Thread, that you call join on, is terminated - join will just return and do nothing.
I'm repeating info that is already in other answers and comments, but let me try and summarize, while adding explanation.
The point of thread.join() is to wait for the thread to terminate. That's what it tells you in the documentation for join:
Waits for this thread to die.
Waiting for a terminated thread to terminate is pretty straightforward (!), and there seems to be no logical reason why waiting for a terminated thread to terminate should be considered an error. You want to know when the thread finishes. It has.
More significantly, if the caller had to ensure that a thread had not terminated before waiting for it to terminate, that would create a timing window that every caller would have to compensate for. The trivial sequence
Thread t = new Thread(…);
t.start();
t.join();
would be prone to failure due to its inherent race hazard. In other words, that would be a bad way to design join.
No, Thread.join() will return instantly if the thread is already dead
Thread will start the execution. will print Run then thread will sleep for 5 seconds and will print Begin following by End
Output on the console:
Run
---- 5 seconds sleep ------
Begin
End
I have the following 2 init methods that call doDataInit():
public void sessionBegin(SessionEvent event)
throws Exception {
....
doDataInit();
}
public void init() {
...
doDataInit();
}
and the method:
private Future<WorkItems>
doDataInit() {
//do some stuff
Callable<WorkItems> initData = getData();
Future<WorkItems> result = EXECUTOR.submit(initData);
return result;
}
Now what I want to do is have a check inside the doDataInit method, that if true is going to sleep the task execution. Or otherwise said - I want to block the execution of the task until a certain condition is met and periodically check if the given condition is met. Once it is - continue execution.
What is the best (most effective) way to achive that in this scenario?
What I can currently think of is:
sleep the thread - uneffective
somehow block the callable
block the Executor
have a for loop where I perform the checks s ceratain amount of times
Thanks in advance.
I want to stop a running thread immediately. Here is my code:
Class A :
public class A() {
public void methodA() {
For (int n=0;n<100;n++) {
//Do something recursive
}
//Another for-loop here
//A resursive method here
//Another for-loop here
finishingMethod();
}
}
Class B:
public class B() {
public void runEverything() {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
A a = new A();
a.methodA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
My problem is that i need to be able to stop the thread in Class B even before the thread is finished. I've tried interrupt() method, but that doesn't stop my thread. I've also heard about using shared variable as a signal to stop my thread, but I think with long recursive and for-loop in my process, shared-variable will not be effective.
Any idea ?
Thanks in advance.
Thread.interrupt will not stop your thread (unless it is in the sleep, in which case the InterruptedException will be thrown). Interrupting basically sends a message to the thread indicating it has been interrupted but it doesn't cause a thread to stop immediately.
When you have long looping operations, using a flag to check if the thread has been cancelled is a standard approach. Your methodA can be modified to add that flag, so something like:
// this is a new instance variable in `A`
private volatile boolean cancelled = false;
// this is part of your methodA
for (int n=0;n<100;n++) {
if ( cancelled ) {
return; // or handle this however you want
}
}
// each of your other loops should work the same way
Then a cancel method can be added to set that flag
public void cancel() {
cancelled = true;
}
Then if someone calls runEverything on B, B can then just call cancel on A (you will have to extract the A variable so B has a reference to it even after runEverything is called.
I think you should persevere with using Thread.interrupt(). But what you need to do to make it work is to change the methodA code to do something like this:
public void methodA() throws InterruptedException {
for (int n=0; n < 100; n++) {
if (Thread.interrupted) {
throw new InterruptedException();
}
//Do something recursive
}
// and so on.
}
This is equivalent declaring and using your own "kill switch" variable, except that:
many synchronization APIs, and some I/O APIs pay attention to the interrupted state, and
a well-behaved 3rd-party library will pay attention to the interrupted state.
Now it is true that a lot of code out there mishandles InterruptedException; e.g. by squashing it. (The correct way to deal with an InterruptedException is to either to allow it to propagate, or call Thread.interrupt() to set the flag again.) However, the flip side is that that same code would not be aware of your kill switch. So you've got a problem either way.
You can check the status of the run flag as part of the looping or recursion. If there's a kill signal (i.e. run flag is set false), just return (after whatever cleanup you need to do).
There are some other possible approaches:
1) Don't stop it - signal it to stop with the Interrupted flag, set its priority to lowest possible and 'orphan' the thread and any data objects it is working on. If you need the operation that is performed by this thread again, make another one.
2) Null out, corrupt, rename, close or otherwise destroy the data it is working on to force the thread to segfault/AV or except in some other way. The thread can catch the throw and check the Interrupted flag.
No guarantees, sold as seen...
From main thread letsvsay someTask() is called and t1.interrput is being called..
t1.interrupt();
}
private static Runnable someTask(){
return ()->{
while(running){
try {
if(Thread.interrupted()){
throw new InterruptedException( );
}
// System.out.println(i + " the current thread is "+Thread.currentThread().getName());
// Thread.sleep( 2000 );
} catch (Exception e) {
System.out.println(" the thread is interrputed "+Thread.currentThread().getName());
e.printStackTrace();
break;
}
}
o/P:
java.lang.InterruptedException
at com.barcap.test.Threading.interrupt.ThreadT2Interrupt.lambda$someTask$0(ThreadT2Interrupt.java:32)
at java.lang.Thread.run(Thread.java:748)
the thread is interrputed Thread-0
Only t1.interuuption will not be enough .this need check the status of Thread.interrupted() in child thread.
I was simply exploring the java.util.concurrent package.
I learnt that the class 'Future' has a method boolean cancel(boolean mayInterruptIfRunning)
Please find attached the test code I wrote :
package com.java.util.concurrent;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
public class FutureTester {
/**
* #param args
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
int poolCnt = 1;
Callable<NumberPrinter> numberPrinter = null;
ScheduledThreadPoolExecutor schPool = new ScheduledThreadPoolExecutor(
poolCnt);
ScheduledFuture<NumberPrinter>[] numPrinterFutures = new ScheduledFuture[poolCnt];
FutureTask<NumberPrinter>[] futureTask = new FutureTask[poolCnt];
for (int i = 0; i < poolCnt; i++) {
numberPrinter = new NumberPrinter();
futureTask[i] = new FutureTask<NumberPrinter>(numberPrinter);
/*
* numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
* .schedule(futureTask[i], 0, TimeUnit.MILLISECONDS);
*/
numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
.submit(futureTask[i]);
}
//Thread.sleep(30);
if (numPrinterFutures.length > 0) {
System.out.println("Task completed ? "
+ numPrinterFutures[0].isDone());
System.out.println("Task cancelled ? "
+ numPrinterFutures[0].cancel(true));
System.out.println("Is task cancelled ? "
+ numPrinterFutures[0].isCancelled());
}
}
}
class NumberPrinter implements Callable<NumberPrinter> {
private int counter = 10;
#Override
public NumberPrinter call() throws Exception {
// TODO Auto-generated method stub
while (counter > 0) {
if (Thread.interrupted()) {/*OUCH !!!*/
return null;
}
System.out.println("counter = " + (counter--));
}
return this;
}
}
Intially,I assumed that cancelling a task will also stop the execution of a running thread(the 'OUCH' part NOT included).But I got the output as follows :
counter = 10
Task completed ? false
counter = 9
Task cancelled ? true
counter = 8
Is task cancelled ? true
counter = 7
counter = 6
counter = 5
counter = 4
counter = 3
counter = 2
counter = 1
On further reading on stackoverflow itself,it was said that
The 'cancel' method can only stop the 'unstarted' jobs(which contradicts with the api description of the method)
The cancel method simply interrupts the running thread which then
must return from the run() method
Hence,I included the 'OUCH' part - a while loop checking for interruption;the output was as follows :
Task completed ? false
counter = 10
Task cancelled ? true
Is task cancelled ? true
QUESTION :
If one is supposed to write something analogous to the 'OUCH' part to stop the running thread,what is the utility/value of the cancel method. How does wrapping a Callable in a FutureTask help if the Thread can't be stopped by cancel? What is the design/conceptual/logical part that I am overlooking?
How does wrapping a Callable in a FutureTask help if the Thread can't be stopped by cancel?
You want to cancel the task, not the thread running it. Using cancel(true) prevents the task from starting (but doesn't remove it from the queue) and interrupts the thread if the task has started. The Task can ignore the interrupt, but there is no clean way of killing a thread without killing the whole process.
The problem that you are overlooking is that only cooperating threads can be stopped safely in Java.
Indeed, if you look at the Thread API, you will notice that there are some methods called destroy, pause, stop, and resume that were deprecated in Java 1.1. The reason that they were deprecated is that the Java designers realized that they generally can't be used safely. The reasons are explained in the note "Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?".
The problem is inherent in the Java threading model, and could only be avoided by curtailing the ability of one thread to interact with objects used by other threads. There is a JSR that specifies one one way of doing this ... Isolates ... but no mainstream JVMs implement these APIs to my knowledge.
So bringing this back to your question, the usefulness of Future.cancel is that it solves the subset of the problem that can be solved in the context of futures.
Invoking cancel(true) will prevent the Future from executing if not already run and will be interrupted if currently running. At this point, the burden to cancel the Future is put on the developer.
Since it is a thread pool it wouldn't make sense to stop the thread (though it rarely if ever makes sense to stop a thread). The cancel/interrupt will not cause the thread to exit from its run method. After the execution of your Callable's call method it will simply pull the next item off the work queue and process that.
The utility of the cancel method is simply to signal the executing thread that some process want's that Callable to stop - not the thread - so you will have to handle the stopping of the Callable yourself.
Suppose, that the code that runs as part of your future does not support cooperative cancellation or interruption. Then cancelling an unstarted task is the best thing you can possibly do. That is why this method exists.
In general I think of cancellation as strictly cooperative. Just cancelling some piece of code by force can lead to corrupted state.