I wish to do this:
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
return 1;
});
f1.thenRun(() -> System.out.println(this.get()));
The last line doesn't compile. I just wish to do something inside thenRun function, and prints its own get() result inside it. I don't wish to use this return value outside calls to f1, to make code more tight.
Is there a way to do it?
Try CompletableFuture#thenAccept() where the argument is Consumer<Result>
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
return 1;
});
f1.thenAccept(System.out::println);
this refer to the caller instance(object) who call the instance method, you cannot use this inside a class and refer to the declared variable f1.
You can test if the task is done then print the result else print another message, giving it 3 seconds to be sure that it will be done for example :
f1.thenRun(() -> {
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
if (f1.isDone())
System.out.println(f1.get());
else
System.out.println("Not Done");
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
Related
I am a beginner and I was analyzing this java code:
// t is a thread running
while (true) {
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
break;
}
t=null;
What I am asking is: is there a need to put that inside an infinite loop? Because as I see the loop will run only once i.e due to that break statement. I need some explanation please.
No, there's no need. Your observation is correct, the loop will be executed only once.
So the OP-posted code is equivalent to the following code.
// t is a thread running
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
t=null;
Code posted by OP:
// t is a thread running
while (true) {
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
break;
}
t=null;
As everyone has already pointed out, the code is incorrect as it stands.
The loop, however is necessary!
The correct code looks like this:
while (true) {
try {
t.join();
break;
} catch (InterruptedException e) { e.printStackTrace(); }
}
t = null;
Without the loop, it is possible for t to be set to null, before the current thread successfully joins it.
t.join(); waiting the finishing of thread.
After that, loop is broken by your "break".
=> always loop only 1 time => no need loop and break, only need t.join();
No need to have a while loop, because t.join() waits for the thread to die.
is like a loop already, in the program at the line of t.join() the program will be blocked while the thread is not dead.
The correct code is:
// t is a thread running
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
t=null;
Here you have an example :
http://www.tutorialspoint.com/java/lang/thread_join.htm
Loop is not necessary!.
It is said that thread t is already started. Therefore it makes no sense "t=null". Thread t is already started and it will finish its job. You can use t.join() without while loop. In this context while loop does not make sense. The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,
t.join();
causes the current thread(main thread in below example) to pause execution until t's thread terminates.Run following code snippet and know the ropes.
public class Main {
public static void main(String[] args) {
Thread t=new Thread(
new Runnable() {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t = null; // no sense, t is already started
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"--Thread--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I have follwoing code.
Future<Integer> future = Executor.execute(callable);
Integer i;
try {
i = future.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return MESSAGE_INT_CODE;
} catch (ExecutionException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
return i;
where ExecutionException can contain other exception say ABCException.
and my calling code is catching ABCException which is runtime exception, so if ExecutionException is occured how would I know it is because of ABCException?
ExecutionException due to some exception when my public call() method run. and call method may have some ABCException
should I write like this ?
catch (ExecutionException e) {
throw new ABCException(e.getMessage());
// TODO Auto-generated catch block
//e.printStackTrace();
}
try e.getCause() instanceof ABCException
If exception occurs during execution of call() method, ExecutorService catches it and put it in an ExecutionException. And when you call future.get(); future throws ExecutionException which contains exception from your call method. So if I understand you correctly, you code may look like this:
try {
future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if(cause instanceof ABCException) {
// cast throwable to ABCException and rethrow it
throw (ABCxception) cause;
}else {
// do something else
}
}
I have an API that I use to retrieve daily schedules on the live cable-tv for various channels. I have a scenario in which I need a guidance as to which approach should work here.
Lets say I need schedules for 10 different channels from the API.
Should I execute 10 different async tasks for the retrieval of the required data?
Problem:
How would I collect the data in an arraylist and return it once all execution is completed?
How will I access the arraylist in my main function once onpostexecute returns the result?
Or I should just provide the list of channels to my single async task and make it build a single output of arraylist for my main function invoking it?
Problem:
Since I will be accessing a webservice for this purpose, will it make it run slow as compared to my 1st approach?
Second problem with this approach is the same as I am having with my 1st one, I need to know when and how to get the complete resultset once the execution of the task is completed?
Here is some code to explain the problem:
//going with the first approach
//invoking my asynctask from an activity or another class
//I need a global arraylist which I can use after postexecute returns its result
ArrayList<String> channels = channelManager.getAllChannelsByRegion("xyz");
final ArrayList<ChannelSchedule> schedules = new ArrayList<ChannelSchedule>();
final ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
for (int i = 0; i < channels.size(); ++i){
AsyncInvokeURLTask task = null;
try {
task = new AsyncInvokeURLTask(
channels.get(i), context, new AsyncInvokeURLTask.OnPostExecuteListener() {
#Override
public void onPostExecute(String result) {
// TODO Auto-generated method stub
try {
//Need to add results to arraylist here...But cannot know when it ends completely
ChannelSchedule schedule = mapper.readValue(result, ChannelSchedule.class);
Log.v("channel name", schedule.getChannelName());
Log.v("channel date", schedule.getDate());
Log.v("channel thumb", schedule.getListOfShows().get(0).getShowThumb());
Log.v("channel time", schedule.getListOfShows().get(0).getShowTime());
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
task.execute();
}
Please let me know if something is not clear or missing.
Launching 10 AsyncTask is perfectly fine.
You can keep a count of the number of pending requests. As OnPostExecute is run on the UI thread there are no risks of race condition.
private int numberOfPendingRequests;
public void MyFunc() {
ArrayList<String> channels = channelManager.getAllChannelsByRegion("xyz");
final ArrayList<ChannelSchedule> schedules = new ArrayList<ChannelSchedule>();
final ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
numberOfPendingRequests = channels.size();
for (int i = 0; i < channels.size(); ++i) {
schedules.add(null);
}
for (int i = 0; i < channels.size(); ++i) {
AsyncInvokeURLTask task = null;
final int index = i; // final so it can be used in the onPostExecute.
try {
task = new AsyncInvokeURLTask(
channels.get(i), context, new AsyncInvokeURLTask.OnPostExecuteListener() {
#Override public void onPostExecute(String result) {
try {
ChannelSchedule schedule = mapper.readValue(result, ChannelSchedule.class);
Log.v("channel name", schedule.getChannelName());
Log.v("channel date", schedule.getDate());
Log.v("channel thumb", schedule.getListOfShows().get(0).getShowThumb());
Log.v("channel time", schedule.getListOfShows().get(0).getShowTime());
schedules.set(index, schedule);
numberOfPendingRequests--;
if (numberOfPendingRequests == 0) {
// Everything is received, do stuff here.
}
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
task.execute();
}
}
I seem to be stuck with a very simple task that would require GOTO statements and, in my opinion, would justify a use of those.
I have the very simple task to exit a void on different conditions. Within its code, several dozen operations are being done and most of them can fail. I test them with try {}.
Now, based on the criticality of the operation, I either need to exit immediately and do nothing else, or, I just need to interrupt control flow and jump to a final point to do some cleaning up and then exit the method.
MWE:
public void myMethod () {
try { op1(); } catch (Exception e) { return; } // Fail here: exit immediately
try { op2(); } catch (Exception e) { cleanUpFirst(); return; } // Fail here: do Cleaning up first, then exit
try { op3(); } catch (Exception e) { return; } // Fail here: exit immediately
try { op4(); } catch (Exception e) { cleanUpFirst(); return; } // Fail here: do Cleaning up first, then exit
try { op5(); } catch (Exception e) { cleanUpFirst(); return; } // Fail here: do Cleaning up first, then exit
// ....
}
public void cleanUpFirst() { /* do something to clean up */ }
For code readability, I'd like to a) avoid a separate function and b) do not have more than one statement within the catch block; it just blows up the code. So, in my opinion this would perfectly justify the use of a GOTO statement.
However, the only solution I came up with, given that only two outcomes are possible, is this:
public void myMethod () {
do {
try { op1(); } catch (Exception e) { return; }
try { op2(); } catch (Exception e) { break; }
try { op3(); } catch (Exception e) { return; }
try { op4(); } catch (Exception e) { break; }
try { op5(); } catch (Exception e) { break; }
// ....
} while (1==0);
/* do domething to clean up */
}
Yes, I have heard of exceptions and that is is the Java way. Is that not as overkilled as using the separate void? I do not need the specifics, I simply need a yes/no result from each operation. Is there a better way?
why not
boolean cleanupfirst = false;
try {
op1 ();
cleanupfirst = true;
op2 ();
cleanupfirst = false;
op3 ();
} catch (Exception e) {
if (cleanupfirst)
cleanup ();
return;
}
You're over-thinking it.
4 minor adjustments.
Let Opn() return a boolean for success or failure, rather than throwing an Excpetion.
Let CleanupFirst handle program termination (you can rename it to clean exit if you want). The new parameter passed to CleanExit is the System.exit code.
Use System.Exit to return a proper return code to the OS, so you can use it in scripting.
It does not seem like your program has a successful path.
if (!op1())
System.exit(1); // <- send a failed returncode to the OS.
if(!op2())
cleanExit(2);
if (!op3())
System.exit(3); // <- send a failed returncode to the OS.
if (!op4())
cleanExit(4);
if (!op5())
cleanExit(5);
cleanExit(0);
More methods for better readability:
public void myMethod() {
try {
tryOp1();
tryOp2();
...
} catch(Exception ignore) {}
}
public void tryOp1() throws Exception {
op1();
}
public void tryOp2() throws Exception {
try {
op1();
} catch (Exception e) {
cleanUp();
throw e;
}
}
The code in the file to test is:
public void testFail() {
assert false;
}
I need to catch this using reflection and increment a "failed" counter. This is my attempt:
try {
Object t = c.newInstance();
m[i].invoke(t, new Object[0]); // m is the array that holds all Methods for c
passed ++;
} catch (AssertionError ae) {
failed ++;
} catch (Exception e) {
errors ++;
}
}
The assertFalse just goes through as passed and does not raise any exceptions. How can I catch this?
Thanks.