I have spring scheduler method. And ExecutorService
#Scheduled(fixedRate = 5000)
public void startSchedule() throws IOException{
threadPool.submit(() -> {
if(.......)return;
try {
generate(reportTasck);
} catch (NurException | IOException e) {
e.printStackTrace();
}
});
}
Each 5 sec start my method and if a necessary condition - start new thread with my logic. How can I stop/pause particular thread?
I have button on veb page, and if I press it I need to stop my thread.
There is already quite some discussion on SO regarding the stopping of threads. For a variety of reasons you should not stop or kill a thread as e.g. noted here:
How do you kill a thread in Java?
In order to allow the thread to properly cleanup its resources it should be the thread's responsibility to terminate itself by e.g. periodically checking some condition using e.g. a shared variable or via the thread's interrupt flag. See this answer for more details:
How to stop a thread created by implementing runnable interface?
Pardon my ignorance if this is a basic question.
I want to understand how can I return control from a module and start processing in background?
Lets start component A calls component B. Component B does some basic processing, starts a background thread and immediately returns control to A. Whenever background thread completes its processing it is going to store the result in a persistence store. Whole processing by this background thread is time consuming and A cannot wait until background thread finishes off.
Component A {
Http Call component B
}
Component B {
// Got request from component A
start background thread();
return; // don't wait till background thread finishes off
}
background thread() {
// time consuming task
}
How can I achieve this behavior in java? I don't think it is entirely asynchronous form of processing since communication is happening over http connection that has timeout settings.
Update:
Component A:
Receives Http call
Component B:
Approach1:
Runnable runnable = new MyThread();
new Thread(runnable).start();
Approach2:
ExecutorService exec = Executors.newSingleThreadExecutor();
exec.execute(new MyThread());
exec.shutdown();
Both of the above mentioned approaches helped me to start background processing and return immediate control to A.
Use threads at a raw level is good solution for some easy proof of concepts, but I strongly suggest at least try to use the concurrent API from java, you can find the documentation here. and a good tutorial is here
The simplest approach is to create a Callable object that contains the instruction you want to execute in background.
Callable myInstructions = new Callable<ObjectToReturn>() {
public ObjectToReturncall() {
return object.methodCall();
}}
Using the ExecutorService submit this callable to expect a Future object.
Future<ObjectToReturn> future = executor.submit(myInstructions);
//Do anything else as this wont be blocked ..
Future API have a set of method to ask if the task is already completed.
if(future.isDone()) // Ask if the task is done
ObjectToReturn solution = future.get() // Get the result
Very simple to use the Future API .
EDIT
If you dont expect any response from the Future api, just do an operation you could use
Future<Void> future = executor.submit(new Callable<Void>() {
public Void call() throws Exception {
testA.abc();
return null;
}
});
Other option if you dont want to receive a result or get a response, just fire a thread will be
ExecutorService executor = Executors.newFixedThreadPool(5);`
executor.execute(new RunnableClass());
Also avoid call shutdown on ExecutorService , do that just until the end of the process, when you dont have more time to do, in spring or container fwks the container is in charge of shutdown the ExecutorService once the app has been shutdown
The easiest way would probably be to create a new java Thread with the background processing logic as parameter.
void componentB() {
new Thread(new Runnable() {
#Override
public void run() {
// Time consuming task.
}
}).start();
// The method continues without stopping.
}
In later versions of java, you can also use the ForkJoinPool-class to achieve this:
public class Main {
private final ExecutorService executor = new ForkJoinPool();
void componentA() {
componentB();
}
void componentB() {
executor.execute(this::timeConsumingTask);
// The method continues without stopping.
}
private void timeConsumingTask() {
// Time consuming task.
}
}
Assuming you want the HTTP call to return before the background processing is complete, your pseudocode is perfectly valid for Java.
At the next level of detail, check out the Javadoc for Thread, Runnable, and the java.nio library classes.
I have programmed a structure that works like this:
Activity discoveryActivity - UI thread
↕ Calls through interface
Service discoveryService - Bound service running on UI thread
↕ Actions through Handler.post(↑) or functions (↓)
Runnable connectionThread - Socket networking
At some point the connectionThread needs a String to continue.
So I make a call with Handler.post(..) to the discoveryService which
notifies the discoveryActivity to show an AlertDialog
The user needs about 20 seconds to input the data and will confirm the input.
Problem 1: What will the thread do in the meantime?
Now I need to make my way down to the Thread again.
Getting to discoveryService is easy
Problem 2: How can I get the thread working again without restarting? The thread is in a complex loop with a few Sockets right now!
My first idea was to keep the thread running
// Inside run()
while(stringWrapper.get() == null) {
Thread.sleep(500);
}
// Outside run()
void setStr(String s) { stringWrapper.set(s); }
But that is inefficient
Then I read about wait() and notify()
I tried that on the thread itself and on the StringWrapper (A simple class that holds a reference to a String)
I am helpless right know and I think wait() and notify() are the right way to go?
Can you give me a hint where I should implement these and on which object they would be called?
TL;DR: I want to let a thread pause until it receives data
Not 100% sure what you're trying to accomplish, but you may be able to use a SettableFuture (from Google Guava library) to solve your issue.
private final SettableFuture<String> stringFuture = SettableFuture.create();
// Inside run()
// This will block your thread until stringFuture is set, or until the given timeout has expired.
final String string = stringFuture.get(1, TimeUnit.MINUTES);
// Outside run()
public void setStr(final String s) {
stringFuture.set(s);
}
I have a function in Java. It normally returns a value after it completes its task. However, in some conditions it returns nothing. I create a runnable and run this function as a thread. However, because of its not returning a value, it does not finish although it does its task. The process stays alive because it waits a returning value. Is there a way to kill this thread after it is triggered or after a timeout? Stop() or Destroy() did not work. During debug, the thread is seen as alive and I want it to bi deleted/removed
Runnable runnable = new Runnable() {
#Override
public void run() {
int stat = RunMyFunction();
}
};
Thread thread = new Thread(runnable);
thread.start();
Java does not support killing a thread via any method on java.lang.Thread.
stop() and destroy() do look promising at first glance, but they have both been deprecated.
The documentation for destroy states:
This method was originally designed to destroy this thread without any cleanup. However, the method was never implemented. If if were to be implemented, it would be deadlock-prone
and stop:
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
Thus when the documentation says 'deprecated', what it really means is that they are broken and must never be used!?! The Java API designers put a lot of work into backwards compatibility of their APIs, where other languages would have removed these methods Sun decided to keep them as their internal guides (rightly or wrongly) do not permit the removal of a public api method.
So, the question remains. How is one to get a thread to exit from another thread? Sadly one must go out of ones way to poll an exit variable. This can be a custom variable, or it can be a standard flag within java.lang.Thread that is accessible via 'interrupted()'. The advantage of using interrupted() is that other Java APIs such as IO support this flag during otherwise blocking API calls and will exit throwing an InterruptedException. The detection of calling interrupt() is not immediate, as it sets a flag and relies on the Thread to poll the variable at some point in the future.
Oracle offers a tutorial on how to code using interrupt here.
The real problem you have is that RunMyFunction sometimes never terminates. As others have already stated, killing a thread is not intended in Java, so there is no good way to do it. Instead, you should reason about why you call a possibly non-terminating method. This looks like a code smell. Do the following:
If you are the author of RunMyFunction, make sure that it always terminates or it can be interrupted. You can do this by checking Thread.currentThread().isInterrupted() and throwing an InterruptedException when it is. E.g:
void run(){
while(...){ // this loop sometimes runs forever
if(Thread.currentThread().isInterrupted())
throw new InterruptedException(); // Now, we can "kill" this thread here
}
}
Using ExecuterService you can specify a timeout.
ExecutorService executor = Executors.newFixedThreadPool(1);
List<Callable<String>> tasks = new ArrayList<Callable<String>>();
tasks.add(new Callable<String>() {
#Override
public String call() throws Exception {
int stat = RunMyFunction();
return "Execution Finished";
}
});
new Thread(new Runnable() {
#Override
public void run() {
try {
executor.invokeAll(tasks, 10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
invokeAll(...) is a blocking call so i've added inside a new thread.
Solution 1: Timed run: If you want a method to return or throw an exception after a specified amount of time, use the following method to execute the method on a background thread while waiting for it to complete:
public static void timedRun(Runnable r, long timeout, TimeUnit unit)
throws InterruptedException, TimeoutException {
Future<?> task = executor.submit(r);
try {
task.get(timeout, unit);
} catch (ExecutionException e) {
throw launderThrowable(e.getCause());
} finally {
task.cancel(true);
}
}
private static RuntimeException launderThrowable(Throwable t) {
if (t instanceof RuntimeException) return (RuntimeException)t;
else if (t instanceof Error) throw (Error)t;
else throw new IllegalStateException("Not unchecked", t);
}
(Source: Goetz, Brian, Bloch, Joshua, Bowbeer, Joseph, Lea, Doug, Holmes, David and Peierls, Tim. Java Concurrency in Practice. : Addison-Wesley Longman, Amsterdam, 2006. Listing 5.13 and 7.10)
For executor, you can either create a new one using Executor.newSingleThreadExecutor(), or reuse an existing one.
But be warned: Although this method is guaranteed to return or throw an exception after the specified timeout, it cannot guarantee that the runnable will really stop! It interrupts the executing thread, but if the runnable does not react to thread interruption (e.g. by internally checking Thread.interrupted()), it may continue to run in the background - possibly forever - occupying a thread! But at least it does not block.
Solution 2: Timed run with custom threads: If there is any possibility beside thread interruption to cancel your method call, you can still use the approach above, but then you have to use an Executor with custom ThreadFactory that creates a special Thread instance with overridden interrupt method:
Executor executor = Executor.newSingleThreadExecutor(r -> new WsdlThread(r));
public class WsdlThread extends Thread {
public WsdlThread(Runnable r) { super(r); }
public void interrupt() {
try {
// TODO: do something that will interrupt the wsdl call
// e.g. close connection to server, etc.
// example: ((WsdlRunnable)r).getWsdlConnection().close();
} finally {
super.interrupt();
}
}
}
If this isn't possible too, and Thread.stop() doesn't work either, this last solution might work:
Solution 3: Start non-cancellable call in another JVM:
Use Runtime.exec to start another JVM and execute the method call there (See Executing a Java application in a separate process for more info on how to do this). Runtime.exec will return a Process object, which represents the running process.
You can kill it by calling destroy() or destroyForcibly().
I am having a scenario :
I have a thread which is calling a method where i use Default HTTP client to execute a request. for getting the response I open an InputStream and use a Buffred Reader to read the stream.
While(s = buffer.readline .... )
Inside the while loop i keep looking at the response and see for a string " Hello " ...If i get the string i send the response object back ..
The While loop executes till i get the string
The while loop executes till i press the back key ( android )
Now the scenario works for my 1st point. But i face issue in the 2nd point.
When i press back key, i need to stop my thread.
but i am not able to do it. I tried :
thread.destroy
thread.interrupt
thread = null
None of the above works. In fact my thread is always running...
I am not clear if the issue is with Thread or the issue is with the While loop of the stream.
Because i see that the while loop is executing always..
Please help me the best way i can solve this issue...Whether close the thread or close the stream.
Please help me find way to close the stream and close the thread.
thread.destroy() is deprecated. Do not use it.
The safest way to stop an IO bound thread is by interrupting it.
The thread's logic must cooperate by (1) checking for isInterrupted() status and
(2) catching InterruptedException exception.
It is important that both #1 and #2 above will be handled. interrupt()ing a
thread can in some occasions result in exceptions and in others in setting of
status with no exception!
A safe thread implementation goes like this:
class MyThread {
private volatile boolean wasStopped;
public void run() {
try {
while (!Thread.currentThread().isInterrupted() && !wasStopped) {
do_thread_work();
}
} catch (InterruptedException e) {
return; // gracefully stop thread
}
}
public void gracefullyStop() {
wasStopped = true;
this.interrupt();
}
}
To stop the thread call
thread.gracefullyStop();
This pattern will work fine as long as the thread logic function (do_thread_work)
will not internally catch & dismiss InterruptedException. Be aware.
You will see other implementations that rely solely on isInterrupted() check
without the additional wasStopped flag. I think this is a bad practice.
Why?
Because if the interrupt() was raised while the thread was in a waiting mode
i.e. inside functions wait() join() or sleep(), the thread will indeed be woken,
but its interrupted status will be set to false.
Good luck.