I am trying to send request to server in every 2 seconds in a thread and check if there is something for me give it back to me....For getting value i have to use callable. I am not able to figure out how to run callable thread in every 2 seconds and get value back from it...here is my sample code of callable implementation...
public String call(){
boolean done = true;
String returnData = "";
while(done){
try {
returnData = post.getAvailableChat();
if(!returnData.equals("")){
System.out.println("Value return by server is "+returnData);
return returnData;
}
return null;
} catch (IOException ex) {
done = false;
Logger.getLogger(GetChatThread.class.getName()).log(Level.SEVERE, null, ex);
}
Now here is my main class code i know i did it wrong here in main class because my code will not go to next line after while loop....but please tell me how to do it
Callable<String> callable = new CallableImpl(2);
ExecutorService executor = new ScheduledThreadPoolExecutor(1);
System.err.println("before future executor");
Future<String> future;
try {
while(chatLoop_veriable){
future = executor.submit(callable);
String serverReply = future.get();
if( serverReply != null){
System.out.println("value returned by the server is "+serverReply);
Thread.sleep(2*1000);
}//End of if
}//End of loop
} catch (Exception e) {
You rightly picked a ScheduledThreadPoolExecutor but you don't take advantage of the methods it provides, in particular in your case: scheduleAtFixedRate instead of submit. You can then remove the sleep part as the executor will handle the scheduling for you.
Future.get() is blocking so control will not returned to you after that until thread completes. you should use Future.get(long timeout,TimeUnit unit)
future.get(2, TimeUnit.SECONDS);
I think it should be more like this from the API docs
(note there is no "public" modifier so it probably needs to be a nested subclass or some alike to solve the access level of the variable)
it should be something like.....
Callable<String> call(){
// code for the 2000 millisecond thread Callable is some sort of data/process for
// a thread to "do"
return (Callable<String>)callable; // or 1
}
However , java.util.concurrent.Executors appears to be how this is achieved with Callable
note V is a vector as in the API docs.
Related
I have a situation.
I am creating a REST API which is going to perform two tasks parallelly. If the first task executed successfully, no need to wait for the second and reply 200 to the caller. But if the First task fails, need to wait for the second task and response will be dependent on the second task.
Could anyone suggest an optimum way to do it in java ?
If it's parallel tasks that you want, you may use Future.
They offer you the cancel method and you can wait for the result if you want.
Considering this simple task :
class MyTask implements Callable<String> {
private mStr;
MyTask(String str) {
mStr = str;
}
#Override
public String call() {
return mStr;
}
}
And there is the usage:
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<String> task1 = executor.submit(new MyTask("My first parallel task"));
Future<String> task2 = executor.submit(new MyTask("My second parallel task"));
try {
String result = task1.get();
String result2 = task2.get();
} catch(ExecutionException ex) {
System.out.println("Something went wrong when executing parallel tasks :" + ex);
}
In the following code
public CompletableFuture<String> getMyFuture(String input)
{
CompletableFuture<String> future = new CompletableFuture<String>().thenApply((result) -> result+ "::");
ExecutorService service = Executors.newFixedThreadPool(6);
service.submit(() -> {
try {
future.complete(getResult(input));
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return future;
}
public String getResult(String input) throws InterruptedException
{
Thread.sleep(3000);
return "hello "+ input +" :" + LocalTime.now();
}
I am expecting the output to contain trailing "::" but program doesn't is "hello first :16:49:30.231
" Is my implementation of apply correct ?
You're invoking complete() method of the CompletionStage that you got at the first line (where you call "thenApply" method).
If your intention is to complete the CompletableFuture with some string value (future.complete(getResult(input))) and then apply some function, you'd better place thenApply() at the end (where you return the future).
public CompletableFuture<String> getMyFuture(String input)
{
CompletableFuture<String> future = new CompletableFuture<String>();
ExecutorService service = Executors.newFixedThreadPool(6);
service.submit(() -> {
try {
future.complete(getResult(input));
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return future.thenApply(result -> result+ "::");
}
I don't know how to explain it in a more understandable way. But in short: you're calling complete() method on the wrong object reference inside your Runnable.
You are creating two CompletableFuture instances. The first, created via new CompletableFuture<String>() will never get completed, you don’t even keep a reference to it that would make completing it possible.
The second, created by calling .thenApply((result) -> result+ "::") on the first one, could get completed by evaluating the specified function once the first one completed, using the first’s result as an argument to the function. However, since the first never completes, the function becomes irrelevant.
But CompletableFuture instances can get completed by anyone, not just a function passed to a chaining method. The possibility to get completed is even prominently displayed in its class name. In case of multiple completion attempts, one would turn out to be the first one, winning the race and all subsequent completion attempts will be ignored. In your code, you have only one completion attempt, which will successfully complete it with the value returned by getResult, without any adaptations.
You could change your code to keep a reference to the first CompletableFuture instance to complete it manually, so that the second gets completed using the function passed to thenApply, but on the other hand, there is no need for manual completion here:
public CompletableFuture<String> getMyFuture(String input) {
ExecutorService service = Executors.newFixedThreadPool(6);
return CompletableFuture.supplyAsync(() -> getResult(input), service)
.thenApply(result -> result + "::");
}
public String getResult(String input) {
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));
return "hello "+ input +" :" + LocalTime.now();
}
When specifying the executor to supplyAsync, the function will be evaluated using that executor. More is not needed.
Needless to say, that’s just for example. You should never create a temporary thread pool executor, as the whole point of a thread pool executor is to allow reusing the threads (and you’re using only one of these six threads at all) and it should get shut down after use.
I'm using a global Executor service with some fixed thread pool size. We have bunch of related tasks that we submit for execution and wait on list of futures.
Recently, we faced a high CPU utilization issue and on debugging I found that an exception occurred while calling get() on one of the item in list of futures. Current, we iterate over the list and there is a try catch surrounding the whole loop.
try{
List<Result> results = new ArrayList<>()
for(Future<Result> futureResult: futureResults{
Result result = futureResult.get();
results.add(result);
}
} catch(Exception e){
throw new InternalServiceException(e);
}
//Do something with results
Wanted to know the behaviour of other threads if get is never called on some of the items in future. I tried searching but was not able to find anything.
Also, can this behaviour trigger high CPU utilization ?
http://www.journaldev.com/1650/java-futuretask-example-program
I would still check if the future isDone as in the example above.
If you need to run other operations or want to utilize the CPU better then I would put the collector in a separate thread and perhaps just poll for results every minute or so.
Could be scheduled or handled by Thread.sleep.
Executors class provides various methods to execute Callable in a thread pool. Since callable tasks run in parallel, we have to wait for the returned Object.
Callable tasks return java.util.concurrent.Future object. Using Future we can find out the status of the Callable task and get the returned Object.
It provides get() method that can wait for the Callable to finish and then return the result.
There is an overloaded version of get() method where we can specify the time to wait for the result, it’s useful to avoid current thread getting blocked for longer time.
Future provides cancel() method to cancel the associated Callable task. There are isDone() and isCancelled() methods to find out the current status of associated Callable task.
Here is a simple example of Callable task that returns the name of thread executing the task after some random time.
We are using Executor framework to execute 10 tasks in parallel and use Future to get the result of the submitted tasks.
public class FutureObjectTest implements Callable<String>{
#Override
public String call() throws Exception {
long waitTime = (long) (Math.random()*10000);
System.out.println(Thread.currentThread().getName() + " waiting time in MILISECONDS " + waitTime);
Thread.sleep(waitTime);
return Thread.currentThread().getName() + " exiting call method.";
}
public static void main(String [] args){
List<Future<String>> futureObjectList = new ArrayList<Future<String>>();
ExecutorService executorService = Executors.newFixedThreadPool(5);
Callable<String> futureObjectTest = new FutureObjectTest();
for(int i=0; i<10; i++){
Future<String> futureResult = executorService.submit(futureObjectTest);
futureObjectList.add(futureResult);
}
for(Future<String> futureObj : futureObjectList){
try {
System.out.println(futureObj.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("Starting get method of wait");
////////////get(Timeout) method///////
futureObjectList.clear();
for(int i=0; i<10; i++){
Future<String> futureResult = executorService.submit(futureObjectTest);
futureObjectList.add(futureResult);
}
executorService.shutdown();
for(Future<String> futureObj : futureObjectList){
try {
System.out.println(futureObj.get(2000,TimeUnit.MILLISECONDS));
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
}
}
}
I am trying to implement a code where I want to call a function from JNI which should have a timeout. If it exceeds the timeout, I want to terminate the native task. I am posting a piece of code to show as an example.
void myFunction(timeOutInSeconds)
{
if(timeOutInSeconds > 0)
{
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Integer> task = new Callable<Integer>() {
public Integer call() {
System.out.println("Calling JNI Task");
JNI_Task();
System.out.println("Finished JNI Task");
return 0;
}
};
Future<Integer> future = executor.submit(task);
try
{
#SuppressWarnings("unused")
Integer result = future.get(timeOutInSeconds, TimeUnit.SECONDS);
}
catch (TimeoutException ex)
{
// handle the timeout
kill_task_in_JNI();
// future.cancel(true);
return TIMEOUT;
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
}
finally
{
// future.cancel(true);
executor.shutdown();
}
}
else
JNI_Task();
}
There are several questions -
Where should I exactly put future.cancel(). There are 2 locations which are commented.
If I run this function with timeOutInSeconds = 0, it runs perfectly.
However Irrespective of the value of timeOutInSeconds, the task gets stuck up and
the JNI task does not get called. I check this by putting printf's in the JNI
code. The task takes 1 second to execute and I gave 30 seconds, 5 minutes etc. still it
is stuck up.
Is there any problem with such approach?
You can (and in this case should) call future.cancel() only in the finally block. http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html.
About the 2nd question, its not clear for me if the problem also occur when timeOutInSeconds=0. Is this the case? Can you provide the content of the JNI_TASK() method?
Suppose method A is calling method B. Can method A control execution time of method B and interrupt it in, suppose, 60 seconds (method B can hangs for example)?
You can run tasks asynchronously using an ExecutorService, obtaining a Future that enables you to get the result of the task when it is done. There's a get method on the Future that you can call to wait for the answer, with a timeout. If it times out, you try to cancel the task by calling cancel on the Future.
ExecutorService executorService = Executors.newSingleThreadExecutor();
// Callable that has a run() method that executes the task
Callable<String> callable = ...;
// Submit the task for execution
Future<String> future = executorService.submit(callable);
try {
String result = future.get(30, TimeUnit.SECONDS);
System.out.println("Result: " + result);
}
catch (TimeoutException e) {
System.out.println("Timeout");
future.cancel(true);
}
There's a lot more to the concurrency API, see the package java.util.concurrent.
Could you describe what exactly do you want?
Just stopping of execution method you can use return, System.exit(), last stop VM.
By time, just check time and return from method. Also, you can try some reflection hacks...
By the way, these are just a imagination if you will describe in more words what do you need I will help you.
Try:
public static void wait(int n){
long time0,time1;
time0=System.currentTimeMillis();
do{
time1=System.currentTimeMillis();
}
while (time1-time0<n);
}
I think that works. If you invoke this method, pass it with the amount of time in milliseconds you want the program to wait as parameter.
Good luck!