I'm playing around with threads and I'm wondering if it's possible to force a thread to execute something.
So, the thing is I have some method like this:
public void asyncSleep() {
Supplier<Boolean> sleeper = () -> {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
return true;
};
CompletableFuture<Boolean> promise = CompletableFuture.supplyAsync(sleeper, ex);
promise.thenAccept(u -> {
System.out.println("thread=" + Thread.currentThread());
});
}
And I'd need the original thread (the one executing the asyncSleep() method) to be the one executing the thenAccept. Is that even possible? And if so, how can I do it?
If you want it to be working in the non blocking way and you still want that original thread (the one that executes asyncSleep) to also execut method that you pass into thenAccept then the only way is as follows:
You'd need to use an ExecutorService with just single thread. Execute asyncSleep with this executor, but then, you'll have to pass the same executor into thenAcceptAsync (instead of thenAccept) as a second argument.
Then if your thread didn't crash and wasn't replaced by the executor with new thread, it should be exactly the same thread executing both methods.
But that's an artificial use case.
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).
System.out.println("Enter the number of what you would like to do");
System.out.println("1 = Manually enter Options");
System.out.println("2 = Use a text file to pick from pre-existing models");
System.out.println("3 = Exit ");
Scanner sc = new Scanner(System.in);
try {
runType = sc.nextInt();
if(runType > 3) {
throw new badValue(999, "Not the valid input");
}
} catch (NullPointerException e) {
} catch (badValue e) {
e.correctBadValue(runType);
}
switch (runType) {
case 1:
Thread a = new SelectCarOption();
a.run();
case 2:
Thread a2 = new BuildCarModelOptions();
a2.run();
case 3:
System.exit(1);
}
}
}
So basically, I'm trying to run a program where the thread that is running is determined by a variable runType. If runType is one value, a certain thread will run and if it is the other, the other will run. Is my approach the most efficient? Will it turn out to give any errors?
Long story short, no, this is not how you want to do things.
thread1.run() doesn't start a new thread, it just calls the code in run() on the current thread. What you want is thread1.start().
thread1.sleep(5000) will not make thread1 sleep, it will make the main thread sleep. Thread.sleep is a static method that affects the current thread, and the fact that you're using an instance variable to invoke it (rather than the more traditional Thread.sleep(5000)) doesn't change that.
It makes no sense to start thread2 and then immediately join to it. You may as well just invoke its code directly on the main thread. (Which is what you're doing right now, since you're invoking thread2.run() instead of thread2.start().)
I'm not sure what your end goals are, but this sounds like a case for plain old polymorphism. Create a Runnable and assign it to one of two concrete implementations, depending on the input; then just invoke run() on it. Something like:
Runnable selectStrategy = (runType == 2)
? new CarModelOptionsIO()
: new SelectCarOption()
selectStrategy.run()
If you need a result from this action, you could use a Callable<T> (don't let the package name confuse you; there's nothing inherent to concurrency in that interface) or even create your own interface, which lets you give more meaningful names to the methods (call and run are pretty unhelpfully generic).
A programmer had a problem. He thought to himself, "I know, I'll solve it with threads!". has Now problems. two he
A)
you can replace
Thread thread1 = new SelectCarOption();
thread1.start();
thread1.join();
by directly executing whatever run does since the thread that starts the thread just waits.
calling thread | new thread
start() ---->
run()
join() <---
does the same thing as
run()
Now we can simplify your code to:
if (runType == 2) {
doCarModelOptionsIO();
} else {
doSelectCarOption()
}
And you have a much more efficient way.
B)
Don't call the run() method on a thread. Every method called directly is executed in place in your current thread. Thread has the start() method that you call which then calls run() from within that new thread.
Overall, your code is confused. I suggest reading the concurrency tutorials if you haven't already. Review them if you have read them. Maybe do a few yourself, then come back to this problem.
You say:
If runType is one value, a certain thread will run and if it is the other, the other will run.
To do that you need something like this...
if (runType == 2) {
Thread thread1 = new SelectCarOption();
thread1.run();
try {
//join blocks until thread 1 terminates. We don't know that it
//ever will give your code
thread1.join(); //stops thread1 to run different thread
} catch (InterruptedException e1) {
e1.printStackTrace();
}
Thread thread2 = new CarModelOptionsIO();
thread2.run();
try {
//blocks again, until thread 2 is done running.
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//start some other thread here since runType is different?
}
There are many mistakes in your class. First you are using the method run() instead of start(). Second, you should start both threads for your sleep() make sense. That a look on the Oracle Java Se tutorial online to see the basics of Java Multithreading model, that will help a lot.
There are several mistakes in your code. and to let you know, the code you have written does not spawn a new thread at all. Few thing to note:
Thread.sleep() is a static method. The below code is misleading:
try {
thread1.sleep(5000); //stops thread1 to run different thread
} catch (InterruptedException e1) {
e1.printStackTrace();
}
You have started thread1 in the main thread and then called sleep method using the newly created thread. But this is not gonna help you. It makes the main thread sleep not thread1. To make thread1 sleep you need to call sleep method within the run() of this thread1 class.
Moreover, sleep() is a static method and should not be called using thread instances, it is misleading.
Also stopping a thread does not necessarily mean it will invoke the other thread. Just remember when it comes to threading, very little is guaranteed.
One more thing :
thread1.run(); // This is incorrect
use thread1.start()
Directly calling run() method does not start a new thread. You need to call start() method to start a new thread. Calling run method directly will execute the contents of the run method in the same thread(from where it is invoked)
I've grown desperate all night on this problem and I have not found help during online research, so here we go.
I want to do an optimization process which is meant to be interrupted at a time that is being determined on runtime. Once the interrupt is thrown, I want the best result that has been calculated until that moment to be returned.
My Idea was to put the calculations into a Callable. Because Callables can return results and also - at least I thought - be interrupted. My call() method would be able to return my best result when an interrupt is thrown. But apparently, the only way to force an interrupt into the Callable is to do task.cancel(true); which then throws a CancellationException before result = task.get(); can retrieve the result.
A rough scetch of my code:
SearchCallable myCallable = new myCallable(...);
ExecutorService service = Executors.newFixedThreadPool(1);
Future<int[]> task = service.submit(myCallable);
try {
Thread.sleep(getTimeToCalculate(...));
} catch (InterruptedException e) {[...]}
task.cancel(true);
try {
result = task.get();
} catch(InterruptedException ie){[...]
} catch (ExecutionException ee) {[...]}
myCallable looks somewhat like this:
public class myCallable implements Callable<Object> {
public myCallable(...){
[...]
}
public Object call(){
return anObjectOfAnotherClass.saidCalculations();
}
}
Where an auxiliary method which does a lot of recursion contains this:
if(Thread.interrupted()){
throw new InterruptedException();
}
And said auxiliary method catches this InterruptedException and returns it's best result so far, so myCallable gets this result and actually should return it.
So, how can I get the interrupt in there and still get my result? Or is there some completely different way to implement my original idea?
So, there is one thread performing the computation; this thread is interrupted and the "best result" is what it could come up with.
Then you can, instead of a Callable, use a Runnable and pass a reference to a structure bearing the result when you initialize it.
You can then submit that runnable to your thread pool; when it is "done with its work" (either it is really done, or it was interrupted), you'll just have to read the data in the reference you passed to your Runnable as an argument.
EDIT Since the result of the computation is a( reference to a)n object, I suggest the use of an AtomicReference.
(Problem solved, solution below)
I have 2 classes: Equip and Command. The equip is an equipment that run commands, but I need it to be able to run only 1 command at the same time.
A command is a thread, that executes on the run() function, while Equip is a normal class that don't extend anything.
Currently I have the following setup to run the commands:
Command class:
#Override
public void run() {
boolean execute = equip.queueCommand(this);
if (!execute) {
// if this command is the only one on the queue, execute it, or wait.
esperar();
}
// executes the command.....
equip.executeNextCommand();
}
synchronized public void esperar() {
try {
this.wait();
} catch (Exception ex) {
Log.logErro(ex);
}
}
synchronized public void continue() {
this.notifyAll();
}
Equip class:
public boolean queueCommand(Command cmd) {
// commandQueue is a LinkedList
commandQueue.addLast(cmd);
return (commandQueue.size() == 1);
}
public void executeNextCommand() {
if (commandQueue.size() >= 1) {
Command cmd = commandQueue.pollFirst();
cmd.continue();
}
}
However, this is not working. Basically, the notify() isn't waking the command thread, so it'll never execute.
I searched about the wait and notify protocol, but I couldn't find anything wrong with the code. I also tried calling the wait() directly from the queueCommand() method, but then the execution of the queueCommand stopped, and it also didn't do what it was supposed to do.
Is this approach correct and I'm missing something or this is completely wrong and I should implement a Monitor class to manipulate the concurrent threads?
EDIT: I solved the problem using another completely different approach, using Executors, thanks to #Gray.
Here's the final code, it might help someone someday:
Equip class:
private ExecutorCompletionService commandQueue = new ExecutorCompletionService(Executors.newFixedThreadPool(1));
public void executeCommand(Command cmd, boolean waitCompletion) {
commandQueue.submit(cmd, null);
if (waitCompletion) {
try {
commandQueue.take();
} catch (Exception ex) {
}
}
}
In the Command class I just have a method to encapsulate the equip's execute method.
The boolean waitCompletion is used when I need the result of the command at the same time, and instead of calling a new thread to execute it, I just execute and wait, pretending that it's executing on the same thread. This question contains a good discussion on this matter: When would you call java's thread.run() instead of thread.start()?. And yes, this is a case where it's useful to call .run() instead of .start().
There are a large number of race conditions that exist in your code if Command.run() is called from multiple threads. Unless this is some sort of homework question where you have to implement the code yourself, I would highly recommend using one of the Java Executors which were added in 1.6. In this case the Executors.newSingleThreadExecutor() is what you need to limit the number of running background tasks to 1. This will allow an unlimited number of tasks to be submitted to the ExecutorService, but only one of those tasks will be executing at any one time.
If you need the thread that is submitting the tasks to block when another task is already running then you would use something like the following. This sets up a pool of a maximum of 1 thread and uses a SynchronousQueue which blocks until the worker thread consumes the job:
final ExecutorService executorServer =
new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
But if that was the case then you would just call the task directly inside of a synchronized block and you wouldn't need the ExecutorService.
Lastly, for any new concurrency programmer (of any language) I would recommend that you take the time to read some documentation on the subject. Until you start recognizing the concurrent pitfalls inherent in threading even the simplest set of classes, it will be a frustrating process to get your code to work. Doug Lea's book is one of the bible's on the subject. My apologies if I have underestimated your experience in this area.
I think you should not have "synchronized" on the esperar method. That will block using the object instances as the locking object. Any other thread that attempts to wait will block AT ENTRY TO THE METHOD, not on the wait. So, the notifyAll will release the one thread that got into the method first. Of the remaining callers, only one will proceed with a call to esperar, which will then block on the wait(). Rinse and repeat.
ExectutorService is the way to go. But if you want to do-it-yourself, or need to do something fancier, I offer the following.
I gather than this whole thing is driven by Equip's queueCommand, which might be callled from any thread anywhere at any time. For starters, the two methods in Equip should by synchronized so commandQueue does not get trashed. (You might use ConcurrentLinkedQueue, but be careful with your counts.) Better still, put the code in each method in a block synchronized by queueCommand.
But further, I think your two classes work better combined. Switching Command to a simple Runnable, I'd try something like this:
class Equip {
private Object queueLock = new Object(); // Better than "this".
private LinkedList<Runnable> commandQueue = new LinkedList<Runnable>();
private void run() {
for (;;) {
Runnable cmd = equip.getNextCommand();
if (cmd == null) {
// Nothing to do.
synchronized (queueLock) { queueLock.wait(); }
}
else
cmd.run();
}
}
// Adds commands to run.
public boolean queueCommand( Runnable cmd ) {
synchronized (queueCommand) { commandQueue.addLast( cmd ); }
synchronized (queueLock) {
// Lets "run" know queue has something in it if it
// is in a wait state.
queueLock.notifyAll();
}
}
private Runnable getNextCommand() {
synchronized (queueCommand) { return commandQueue.pollFirst(); }
}
}
You'll need to catch some exceptions, and figure out how to start things up and shut them down, but this should give an idea of how the wait and notify work. (I'd look for some way to know when "run" was not waiting so I could skip synching on queueLock in queueCommand, but walk before you run.)
I have a method that I would like to call. However, I'm looking for a clean, simple way to kill it or force it to return if it is taking too long to execute.
I'm using Java.
to illustrate:
logger.info("sequentially executing all batches...");
for (TestExecutor executor : builder.getExecutors()) {
logger.info("executing batch...");
executor.execute();
}
I figure the TestExecutor class should implement Callable and continue in that direction.
But all i want to be able to do is stop executor.execute() if it's taking too long.
Suggestions...?
EDIT
Many of the suggestions received assume that the method being executed that takes a long time contains some kind of loop and that a variable could periodically be checked.
However, this is not the case. So something that won't necessarily be clean and that will just stop the execution whereever it is is acceptable.
You should take a look at these classes :
FutureTask, Callable, Executors
Here is an example :
public class TimeoutExample {
public static Object myMethod() {
// does your thing and taking a long time to execute
return someResult;
}
public static void main(final String[] args) {
Callable<Object> callable = new Callable<Object>() {
public Object call() throws Exception {
return myMethod();
}
};
ExecutorService executorService = Executors.newCachedThreadPool();
Future<Object> task = executorService.submit(callable);
try {
// ok, wait for 30 seconds max
Object result = task.get(30, TimeUnit.SECONDS);
System.out.println("Finished with result: " + result);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
System.out.println("timeout...");
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
Java's interruption mechanism is intended for this kind of scenario. If the method that you wish to abort is executing a loop, just have it check the thread's interrupted status on every iteration. If it's interrupted, throw an InterruptedException.
Then, when you want to abort, you just have to invoke interrupt on the appropriate thread.
Alternatively, you can use the approach Sun suggest as an alternative to the deprecated stop method. This doesn't involve throwing any exceptions, the method would just return normally.
I'm assuming the use of multiple threads in the following statements.
I've done some reading in this area and most authors say that it's a bad idea to kill another thread.
If the function that you want to kill can be designed to periodically check a variable or synchronization primitive, and then terminate cleanly if that variable or synchronization primitive is set, that would be pretty clean. Then some sort of monitor thread can sleep for a number of milliseconds and then set the variable or synchronization primitive.
Really, you can't... The only way to do it is to either use thread.stop, agree on a 'cooperative' method (e.g. occassionally check for Thread.isInterrupted or call a method which throws an InterruptedException, e.g. Thread.sleep()), or somehow invoke the method in another JVM entirely.
For certain kinds of tests, calling stop() is okay, but it will probably damage the state of your test suite, so you'll have to relaunch the JVM after each call to stop() if you want to avoid interaction effects.
For a good description of how to implement the cooperative approach, check out Sun's FAQ on the deprecated Thread methods.
For an example of this approach in real life, Eclipse RCP's Job API's 'IProgressMonitor' object allows some management service to signal sub-processes (via the 'cancel' method) that they should stop. Of course, that relies on the methods to actually check the isCancelled method regularly, which they often fail to do.
A hybrid approach might be to ask the thread nicely with interrupt, then insist a couple of seconds later with stop. Again, you shouldn't use stop in production code, but it might be fine in this case, esp. if you exit the JVM soon after.
To test this approach, I wrote a simple harness, which takes a runnable and tries to execute it. Feel free to comment/edit.
public void testStop(Runnable r) {
Thread t = new Thread(r);
t.start();
try {
t.join(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!t.isAlive()) {
System.err.println("Finished on time.");
return;
}
try {
t.interrupt();
t.join(2000);
if (!t.isAlive()) {
System.err.println("cooperative stop");
return;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.err.println("non-cooperative stop");
StackTraceElement[] trace = Thread.getAllStackTraces().get(t);
if (null != trace) {
Throwable temp = new Throwable();
temp.setStackTrace(trace);
temp.printStackTrace();
}
t.stop();
System.err.println("stopped non-cooperative thread");
}
To test it, I wrote two competing infinite loops, one cooperative, and one that never checks its thread's interrupted bit.
public void cooperative() {
try {
for (;;) {
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.err.println("cooperative() interrupted");
} finally {
System.err.println("cooperative() finally");
}
}
public void noncooperative() {
try {
for (;;) {
Thread.yield();
}
} finally {
System.err.println("noncooperative() finally");
}
}
Finally, I wrote the tests (JUnit 4) to exercise them:
#Test
public void testStopCooperative() {
testStop(new Runnable() {
#Override
public void run() {
cooperative();
}
});
}
#Test
public void testStopNoncooperative() {
testStop(new Runnable() {
#Override
public void run() {
noncooperative();
}
});
}
I had never used Thread.stop() before, so I was unaware of its operation. It works by throwing a ThreadDeath object from whereever the target thread is currently running. This extends Error. So, while it doesn't always work cleanly, it will usually leave simple programs with a fairly reasonable program state. For example, any finally blocks are called. If you wanted to be a real jerk, you could catch ThreadDeath (or Error), and keep running, anyway!
If nothing else, this really makes me wish more code followed the IProgressMonitor approach - adding another parameter to methods that might take a while, and encouraging the implementor of the method to occasionally poll the Monitor object to see if the user wants the system to give up. I'll try to follow this pattern in the future, especially methods that might be interactive. Of course, you don't necessarily know in advance which methods will be used this way, but that is what Profilers are for, I guess.
As for the 'start another JVM entirely' method, that will take more work. I don't know if anyone has written a delegating class loader, or if one is included in the JVM, but that would be required for this approach.
Nobody answered it directly, so here's the closest thing i can give you in a short amount of psuedo code:
wrap the method in a runnable/callable. The method itself is going to have to check for interrupted status if you want it to stop (for example, if this method is a loop, inside the loop check for Thread.currentThread().isInterrupted and if so, stop the loop (don't check on every iteration though, or you'll just slow stuff down.
in the wrapping method, use thread.join(timeout) to wait the time you want to let the method run. or, inside a loop there, call join repeatedly with a smaller timeout if you need to do other things while waiting. if the method doesn't finish, after joining, use the above recommendations for aborting fast/clean.
so code wise, old code:
void myMethod()
{
methodTakingAllTheTime();
}
new code:
void myMethod()
{
Thread t = new Thread(new Runnable()
{
public void run()
{
methodTakingAllTheTime(); // modify the internals of this method to check for interruption
}
});
t.join(5000); // 5 seconds
t.interrupt();
}
but again, for this to work well, you'll still have to modify methodTakingAllTheTime or that thread will just continue to run after you've called interrupt.
The correct answer is, I believe, to create a Runnable to execute the sub-program, and run this in a separate Thread. THe Runnable may be a FutureTask, which you can run with a timeout ("get" method). If it times out, you'll get a TimeoutException, in which I suggest you
call thread.interrupt() to attempt to end it in a semi-cooperative manner (many library calls seem to be sensitive to this, so it will probably work)
wait a little (Thread.sleep(300))
and then, if the thread is still active (thread.isActive()), call thread.stop(). This is a deprecated method, but apparently the only game in town short of running a separate process with all that this entails.
In my application, where I run untrusted, uncooperative code written by my beginner students, I do the above, ensuring that the killed thread never has (write) access to any objects that survive its death. This includes the object that houses the called method, which is discarded if a timeout occurs. (I tell my students to avoid timeouts, because their agent will be disqualified.) I am unsure about memory leaks...
I distinguish between long runtimes (method terminates) and hard timeouts - the hard timeouts are longer and meant to catch the case when code does not terminate at all, as opposed to being slow.
From my research, Java does not seem to have a non-deprecated provision for running non-cooperative code, which, in a way, is a gaping hole in the security model. Either I can run foreign code and control the permissions it has (SecurityManager), or I cannot run foreign code, because it might end up taking up a whole CPU with no non-deprecated means to stop it.
double x = 2.0;
while(true) {x = x*x}; // do not terminate
System.out.print(x); // prevent optimization
I can think of a not so great way to do this. If you can detect when it is taking too much time, you can have the method check for a boolean in every step. Have the program change the value of the boolean tooMuchTime to true if it is taking too much time (I can't help with this). Then use something like this:
Method(){
//task1
if (tooMuchTime == true) return;
//task2
if (tooMuchTime == true) return;
//task3
if (tooMuchTime == true) return;
//task4
if (tooMuchTime == true) return;
//task5
if (tooMuchTime == true) return;
//final task
}