I am making a news update app. For this it needs to be able to get updates on given periods of times. In this i have created a timer to run the callable plugin on given periods of time. Here i used a FixedThreadPool(executor).
For this what i want is to know when the future has finished its job so i can call the updateHeadlines method. but when i use finished.get() it blocks the gui. is there a way to know without blocking when the job has been finished to i can update the GUI after that.
for (Callable curplugin : plugin) {
new Timer(((NewsPlugin) curplugin).getUpdateFrequency(), new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Future<?> finished = executor.submit(curplugin);
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ArrayList<Headline> news = (ArrayList) finished.get();
updateHeadlines();
} catch (InterruptedException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
}).start();
}
There should be no need to combine Timer and ExecutorService, or to use a callback. Instead, schedule a Runnable that invokes the plugin, and schedules an invokeLater to display the result:
for (NewsPlugin plugin : plugins) {
Runnable task = () -> {
List<Headline> news;
try {
news = plugin.call(); /* There's really no need for plugin to be `Callable` */
} catch (Exception ex) {
ex.printStackTrace();
}
java.awt.EventQueue.invokeLater(this::updateHeadlines);
};
int period = plugin.getUpdateFrequency();
executor.scheduleAtFixedRate(task, period, period, TimeUnit.MILLISECONDS);
}
If you are using Java 8. There is a completeable future, In which you can register a callback, which will be called when task is completed. I think that will be helpful to you.
May be this will help you Callback with CompletableFuture
From Java 8 onward you could use a CompletableFutureto get a callback on completion for one shot tasks. Before Java 8 you could use Guava's ListenableFuture, which has similar functionality.
For recurrent tasks use an observable pattern, which is the counterpart to futures for handling multiple items returned from a recurring task. Java does not seem to offer a good OOTB solution here though.
Related
I need to set a timeout for a block of code which will call an method in jar file.
I am using the following code
final Runnable stuffToDo = new Runnable() {
#Override
public void run() {
/* Do stuff here. */
jarclass.run();
}
};
final ExecutorService executor = Executors.newFixedThreadPool(1);
final Future future = executor.submit(stuffToDo);
//executor.shutdown(); // This does not cancel the already-scheduled task.
try {
future.get(1, TimeUnit.SECONDS);
}
catch (InterruptedException ie) {
/* Handle the interruption. Or ignore it. */
}
catch (ExecutionException ee) {
/* Handle the error. Or ignore it. */
}
catch (TimeoutException te) {
/* Handle the timeout. Or ignore it. */
}
if (!executor.isTerminated()){
executor.shutdownNow();
}
However the jarclass.run() somehow start another thread which keep running and show all the printout with pool-2-thread-1.
How can I completely shutdown the jarclass.run()??
Update:
I changed new Thread() to new Runnable. It still doesn't work.
What I am confusing is I don't know where jarclass start another thread and cannot handle it. When the code goes to executor.shutdownNow(), it does jump out and run the following code. But the jarclass.run() are still running.
I am not very good at English. Hope I made this clear.
Update:
Problem solved by this code:
Future<String> future = new FutureTask<String>(new Callable<String>() {
public String call() throws Exception {
jarclass.run();
return null;
}
});
try {
future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
Don't know why the former code fail......If anyone knows, we can still discuss.
Thanks for all the kindly replies. Really appreciate it.
You should not instantiate a Thread when using ExecutorService. Use Runnable instead:
final Runnable stuffToDo = new Runnable() { /* as it is now */ };
When you create a thread directly, it's not managed by the executor service you create later and that's why all the logs.
It's not safe kill thread directly, see Thread.stop() deprecated
Recomended way it to use a flag that can notify to thread that is time to stop.
If you can access to jar and modify code you can create a method named stop() in your jarclass using flag so when you need to kill process you can call jarclass.stop().
For example:
public class jarclass{
private boolean keepAlive = true;
public void run(){
keepAlive = true;
while(keepAlive){
//do work
}
}
public void stop(){
keepAlive = false;
}
}
I have two async tasks, namely task 1 and task 2.
I need to run task 1 first and then task 2 just after but I do not want to couple the two by calling task 2 in the onPostExecute implementation of task 1; because I use task 1 as stand alone in other circumstances.
I there a way to have the two async tasks defined without being bounded to each other and chain them in specific circumstances?
Thank you very much for your help.
You can try something like this:
final Executor directExecutor = new Executor() {
public void execute(Runnable r) {
r.run();
}
};
AsyncTask.execute(new Runnable() {
task1.executeOnExecutor(directExecutor, params1);
task2.executeOnExecutor(directExecutor, params2);
});
I don't have android SDK on my machine now, so I can't verify it.
You can do the following:
YourAsyncClass1 thread1 = new YourAsyncClass1();
thread1.execute(inputArgument1);
try {
outputResult1 = thread1.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if(outputResult1 == true /*Or expected result*/){
YourAsyncClass2 thread2 = new YourAsyncClass2();
thread2.execute(inputArgument2);
}
I have been working on a java GUI application that on a particular action do some task. I have been doing this task using ExecutorService. Now the working with multiple threads works fine but the problem is that I do not want to block my GUI. User may want to cancel the current operation and may request for another one. But while using the ExecutorService, my main Thread gets blocked. I want to wait for my child threads to finish, invoked using ExecutorService, while still being able to work on GUI.
The updated code is:
ExecutorService child = Executors.newCachedThreadPool();
ExecutorService es = Executors.newCachedThreadPool();
#Action
public void doAction() {
/** Some Code goes here */
if(Condition){
if(!(es.isTerminated()||es.isShutdown())){
es.shutdownNow();
es = Executors.newCachedThreadPool();
}
es.execute(new Runnable() {
public void run() {
if(!(child.isTerminated()||child.isShutdown())){
child.shutdownNow();
child = Executors.newCachedThreadPool();
}
for(loopConditions){
child.execute(new Runnable() {
public void run() {
//Perform Some Task Here
}
});
}
child.shutdown();
try {
boolean finshed = child.awaitTermination(5, TimeUnit.MINUTES);
} catch (InterruptedException ex) {
child.shutdownNow();
Logger.getLogger(MySearchView.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("All Child Threads finished Execution");
}
});
es.shutdown();
try {
boolean finshed = es.awaitTermination(5, TimeUnit.MINUTES);
} catch (InterruptedException ex) {
es.shutdownNow();
Logger.getLogger(MySearchView.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("All Threads finished Execution");
/**
* Code that should run after all Threads finishes their Execution
*/
}
}
You're not using the Executors in the way they're intended. They are meant to be long-lived, created on application startup and torn down at the end. Don't use shutdownNow and awaitTermination during normal processing.
If you want to await the result of a task, call get() on the Future that was returned when you submitted it.
I would use a ScheduledExecutorService to shut itself down after 5 seconds.
I am new to Android. Can anyone tell me how to execute a message every 5 seconds. I have tried this code, but it's not showing anything on my emulator. What should I be doing instead?
while(true) {
Toast.makeText(this, "hi", Toast.LENGTH_SHORT).show();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You should not call Thread.sleep() from the GUI thread. Never do this. Use a handler for such thing.
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
doStuff();
/*
* Now register it for running next time
*/
handler.postDelayed(this, 1000);
}
};
I prefer this way to using timers because the Timer class introduces a new thread and it is now fair to do this.
Is that the sum of your code? What are you setting your activity view to? Android implements an alarm/scheduling service which will be much more friendly to battery life than trying to implement your own.
I'm looking for functionality in java identical to this in ruby:
SystemTimer.timeout_after(30.seconds) do
do something
end
i could achieve this by forking a thread and then killing it after a while, but is there a simpler way?
Cant you just use the Java Timer?
A facility for threads to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execution at regular intervals.
You can create a ThreadPoolExecutor, which has an invokeAll method who recievs a timeout as a parameter.
What you are looking for is the CompletableFuture<T> (Link leads to official JavaDoc) from Java 8.
Usage could look something like this:
public static <V> Optional<V> of(PrivilegedAction<V> action, Duration duration) {
final CompletableFuture<V> handler = CompletableFuture.supplyAsync(() -> action.run());
V retval = null;
try {
retval = handler.get(duration.toMillis(), TimeUnit.MILLISECONDS);
} catch (TimeoutException te) {
} catch (Exception e) {
try {
handler.cancel(true);
} catch (CancellationException ce) {
}
}
return Optional.ofNullable(retval);
}
A util class I created: (German comments) DTimeout (View at pastebin)
Either run it in a Thread or do something like this:
void method() {
long endTimeMillis = System.currentTimeMillis() + 10000;
while (true) {
// method logic
if (System.currentTimeMillis() > endTimeMillis) {
// do some clean-up
return;
}
}
}
As you can see, this doesn't work for all kind of methods.