I have a JSP application in which a webpage calls five methods one by one (all of them fetch data from different sources) and display charts based on data.
To load the webpage fastly, I planned to call all the five methods in parallel with the help of FixedThreadPool Executor.
Should I shut down my executor once I get the result from all five methods? Shutting down the executor is a bad idea according to me, since if someone opens the webpage a second time it will require the executor to initialize again in order to call the five methods parallelly.
However, I'm not sure about the consequences of leaving the executor open so not sure how to proceed.
Leaving it open is the normal way to use a thread pool. That's the whole point of thread pools: It's to prevent your application from having to create and then destroy however many new threads every time it needs to load a page. Instead, it can just use the same threads again and again.
In chapter 7 of "Java Concurrency in Practice" there is an example just like this, where a so called one-shot execution service is proposed:
If a method needs to process a batch of tasks and does not return until all the
tasks are finished, it can simplify service lifecycle management by using a private
Executor whose lifetime is bounded by that method.
Its code example:
boolean checkMail(Set<String> hosts, long timeout, TimeUnit unit)
throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
final AtomicBoolean hasNewMail = new AtomicBoolean(false);
try {
for (final String host : hosts)
exec.execute(new Runnable() {
public void run() {
if (checkMail(host))
hasNewMail.set(true);
}
});
} finally {
exec.shutdown();
exec.awaitTermination(timeout, unit);
}
return hasNewMail.get();
}
I'd suggest simplifying your code using this approach.
Related
I am trying to use a Third Party Internal Library which is processing a given request. Unfortunately it is synchronous in nature. Also I have no control on the code for the same. Basically it is a function call. This function seems to a bit erratic in behavior. Sometimes this function takes 10 ms to complete processing and sometimes it takes up to 300 secs to process the request.
Can you suggest me a way to write a wrapper around this function so that it would throw an interrupted exception if the function does not complete processing with x ms/secs. I can live with not having the results and continue processing, but cannot tolerate a 3 min delay.
PS: This function internally sends an update to another system using JMS and waits for that system to respond and sends apart from some other calculations.
Can you suggest me a way to write a wrapper around this function so that it would throw an interrupted exception if the function does not complete processing with x ms/secs.
This is not possible. InterruptException only gets thrown by specific methods. You can certainly call thread.stop() but this is deprecated and not recommended for a number of reasons.
A better alternative would be for your code to wait for the response for a certain amount of time and just abandon the call if doesn't work. For example, you could submit a Callable to a thread pool that actually makes the call to the "Third Party Internal Library". Then your main code would do a future.get(...) with a specific timeout.
// allows 5 JMS calls concurrently, change as necessary or used newCachedThreadPool()
ExecutorService threadPool = Executors.newFixedThreadPool(5);
...
// submit the call to be made in the background by thread-pool
Future<Response> future = threadPool.submit(new Callable<Response>() {
public Response call() {
// this damn call can take 3 to 3000ms to complete dammit
return thirdPartyInternalLibrary.makeJmsRequest();
}
});
// wait for some max amount of time
Response response = null;
try {
response = future.get(TimeUnit.MILLISECONDS, 100);
} catch (TimeoutException te) {
// log that it timed out and continue or throw an exception
}
The problem with this method is that you might spawn a whole bunch of threads waiting for the library to respond to the remote JMS query that you would not have a lot of control over.
No easy solution.
This will throw a TimeoutException if the lambda doesn't finish in the time allotted:
CompletableFuture.supplyAsync(() -> yourCall()).get(1, TimeUnit.SECONDS)
Being that this is 3rd party you cannot modify the code. As such you will need to do two things
Launch the execution in a new thread.
Wait for execution in current thread, with timeout.
One possible way would be to use a Semaphore.
final Semaphore semaphore = new Semaphore(0);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// do work
semaphore.release();
}
});
t.start();
try {
semaphore.tryAcquire(1, TimeUnit.SECONDS); // Whatever your timeout is
} catch (InterruptedException e) {
// handle cleanup
}
The above method is gross, I would suggest instead updateing your desing to use a dedicated worker queue or RxJava with a timeout if possible.
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've to do a massive upload to a certain server - my program do each upload in about 1 second - but i will upload around 10 thousand documents each time.
To do this, i thought in use parallelism to send the documents in a good time. (My server already accept a lot of requests simultaneously).
So, i created a Task (implementing a Callable) that upload my document.
And put it in a ExecutorService.
ExecutorUpload.java
public void execute(){
ExecutorService executor = Executors.newWorkStealingPool();
//this code create the InputStream objects from
//real Files from disk using java.io.InputStream and java.io.File
List<CallbackCreateDocumentTask> tasks = createTasks(...);
//this list holds the Future objects to try to terminate the executorService
List<Future<DocumentDTO>> futures = new CopyOnWriteArrayList<>();
//iterate the list and call the Tasks
tasks.stream().forEach((task) -> futures.add(executor.submit(task)));
executor.shutdown();
//here i was trying to stop the executor,
//but this makes me lose de asynchronous upload because
//the application stops to wait this unique executoService to terminate,
//and i've more than one executorService doing upload
//executor.awaitTermination(10, TimeUnit.MINUTES);
}
App.java
public static void main (String[] args){
new ExecutorUpload().execute();
}
This code is allright. All my documents were uploaded by the Tasks, in all instances of ExecutorService that i created.
But, my application never ends. It's like it stay waiting for more unfinished executorServices;
Does anybody knows why my application never ends ?
I suspect a few things :
Java 8 never close the main method
My executorService's run in a never-ending thread, or something like
that
My InputStream's doesnt are been closed, making the main method
wait for it
Something with the File, not with the InputStream, related with the Files not been closed too...
I have a web application that contains a java bean for executing a potentially long-running job. I'd like to find a way that I can identify when a thread has been executing for a very long time and then potentially kill it if necessary.
My application runs in Glassfish 3 so I am on Java 1.6. I am just looking for a solution to a potential problem in the future.
EDIT:
To be clear I am looking for something like a tool or utility to monitor a running web application.
Use an Executor Service.
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Runnable(){ ....});//pass your runnable
And then you can wait for a specified time:
try {
int timeOut = 5;
//Waits if necessary for at most the given time for the computation to
// complete, and then retrieves its result, if available.
future.get(timeout, TimeUnit.SECONDS)
} catch (TimeoutException e) {
System.out.println("TimedOut!");
}
executor.shutdownNow();
How can I create a timeout for each command that is running in parallel using java.util.concurrent.ExecutorService?
My code is something like this:
For example in the code below I need obj1 run for maximum 1 min, and obj2 for 2 mins and others 5 mins.
ExecutorService exService;
exService = Executors.newCachedThreadPool();
exService.execute(obj1);
exService.execute(obj2);
exService.execute(obj3);
exService.execute(obj4);
exService.shutdown();
boolean finshed = exService.awaitTermination(5, TimeUnit.MINUTES);
if (finshed) {
//Doing something
}
EDIT:
Unfortunately the class of obj1 - obj4 is scraping some web pages using WebHarvest that uses jakarta HttpClient for reading web pages and HttpClient (And neither WebHarvest itself) doesn't have any feature for timeout on entire page reading and/or scraping job.
This is my time consuming task and I thought about killing ExecutorService thread after a timeout to handle this problem.
In general, there is no reliable way to make a separate thread quit. In particular, there is no reliable way to interrupt and stop your task after a timeout from outside that task. What you need to do is make the tasks themselves responsible for stopping after their time runs out. Depending on what they do, you might be able to abstract this behaviour into a superclass something like:
public abstract class TimeoutRunnable implements Runnable {
private final long timeLimitMillis;
private long startTimeMillis;
public TimeoutRunnable(long timeLimitMillis) {
this.timeLimitMillis = timeLimitMillis;
}
public final void run() {
startTimeMillis = System.currentTimeMillis();
while (System.currentTimeMillis() - startTimeMillis < timeLimitMillis) {
runIteration();
}
}
protected abstract void runIteration();
}
Then in your subclass override, runIteration() and perform a single "step" of the task.
The only reasonably reliable way to kill a task is to run it in a separate process and kill that process if it times out. Using any other approach with a library which does not support timeouts is likely to be error prone at best.
from my point of view I think that such stuff requires some more robust foundations than plain Java standard classes , that 's why I would suggest to use any scheduler infrastructure (Quartz or any other project) which may gives you handles (job identifiers) to kill your time consuming tasks .
You may have something like this :
Main Thread launches the Quartz Scheduler , receive subscriptions from different jobs
saying : Job1,Job 2 and TimeCheckerJob
TimeCheckerJob would be a forever job ,notified to any new job and would check for living time for each any new job... In this job you would have to deal with start time of each job, beware of the OS clocks and don't try to setup too hard constraints (nanoseconds is pure fiction).
HTH
My 2 cents
Jerome