I am trying to use fixed thread pool using executor framework. Each runnable instance submitted to the executor is worker thread which process a java result set. For every iteration of the result set I have to call rest webservice which used the oauth token. The oauth token is to be refreshed after every 50 min and need to be shared among all the runnable submitted to the executor.I am also using scheduled executor which execute after every 50 minutes but sometimes it is called correctly and some time not due to which the rest web service fails as it used the expired token in its header. I need to ensure that the scheduled service must be called after every 50 min without fail. But I am stuck on this. Also I need some mechanism that after the group of rest web service call is completed then only the new web service calls should be made while iterating the result set.
ThreadPoolExecutor executorPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
WorkerThread wt1=new WorkerThread(conn,Queries.getAddressInfo("AL"),oauth_token,restTemplate);
WorkerThread wt2=new WorkerThread(conn,Queries.getAddressInfo("AK"),oauth_token,restTemplate);
executorPool.execute(wt1);
executorPool.execute(wt2);
ScheduledFuture scheduledFuture =
scheduledExecutorService.schedule(new Runnable() {
public void run() {
System.out.println("token service");
String url="";
try {
url = WebServicePropertyFileReader.getOauthUrl()+String.format(urlToGetOauthToken, WebServicePropertyFileReader.getClientId(),
WebServicePropertyFileReader.getClientSecret());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Layer7Token token=restTemplate.postForObject(url, null, Layer7Token.class);
GlobalTokenAccessor.oauth_token=token.getAccessToken();
}
},
50,
TimeUnit.MINUTES);
There are two issues :
Schedule schedules it only one time.
You should use scheduleAtFixedRate to schedule periodic tasks. There is no guarantee that the thread will get scheduled within 50 minutes. So, you may want to schedule the refresh every 49 minutes or so.
Secondly, you should control the access to the shared variable though a synchronized write and read methods. Otherwise, the read thread may read incorrect values.
Related
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.
Interesting, I would think have 255 concurrent users, an async API would have better performance. Here are 2 of my endpoints in my Spring server:
#RequestMapping("/async")
public CompletableFuture<String> g(){
CompletableFuture<String> f = new CompletableFuture<>();
f.runAsync(() -> {
try {
Thread.sleep(500);
f.complete("Finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return f;
}
#RequestMapping("/sync")
public String h() throws InterruptedException {
Thread.sleep(500);
return "Finished";
}
In the /async it runs it on a different thread. I am using Siege for load testing as follows:
siege http://localhost:8080/sync --concurrent=255 --time=10S > /dev/null
For the async endpoint, I got a transaction number of 27 hits
For the sync endpoint, I got a transaction number of 1531 hits
So why is this? Why isnt the async endpoint able to handle more transactions?
Because the async endpoint is using a shared (the small ForkJoinPool.commonPool()) threadpool to execute the sleeps, whereas the sync endpoint uses the larger threadpool of the application server. Since the common pool is so small, you're running maybe 4-8 operations (well, if you call sleeping an operation) at a time, while others are waiting for their turn to even get in the pool. You can use a bigger pool with CompletableFuture.runAsync(Runnable, Executor) (you're also calling the method wrong, it's a static method that returns a CompletableFuture).
Async isn't a magical "make things faster" technique. Your example is flawed as all the requests take 500ms and you're only adding overhead in the async one.
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.
I am trying to use executor framework in Google App engine. Bellow is the code that I am trying to run.
Thread thread = ThreadManager.createBackgroundThread(new Runnable(){
public void run(){
try{
LOGGER.info( "Checking background thread");
Thread.sleep(10);
}
catch (InterruptedException ex){
throw new RuntimeException("Exception:", ex);
}
}
});
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(10, ThreadManager.backgroundThreadFactory());
executor.scheduleAtFixedRate(thread, 0, 30, TimeUnit.MINUTES);
But this doesn't start the thread. But if I use thread.start() it works properly. I have checked Whitelisted Classes and it does provide Executor classes. So where I am doing it wrong ?
Saikat,
You should always try to avoid creating threads on App Engine, because of it's distributed and dynamic nature it tends to have really bad/unexpected results.
In your case multiple instances will spawn multiple (local) threads sending many times the same notification. Also, bear in mind GAE front end instances have a 1 minute request limit, so after that time the server will kill that request.
Fortunately App Engine provides the Cron service for exactly this situations.
The Cron Service will allow you to schedule a job to run at a given time or every given period. When the cron is triggered GAE will call a configured URL so you can do your process, in your case send notifications.
Eg:(from the link provided)
<cron>
<url>/weeklyreport</url>
<description>Mail out a weekly report</description>
<schedule>every monday 08:30</schedule>
<timezone>America/New_York</timezone>
</cron>
will make an HTTP request to /weeklyreport every monday #8:30.
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();