Java awaiting Future result without blocking - java

I have an application where by clicking buttons (that number is defined) user creates tasks (Callable) that do some calculations. I want to be able to react when the task is finished. Using Future.get() blocks the application. Is there any way to be able to react when the Callable returns the result?
private static void startTask(int i){
try{
Future<Integer> future = executor.submit(callables.get(i-1));
ongoingTasks.put(i, future);
awaitResult(future, i);
}
catch(Exception e){
e.printStackTrace();
}
}
private static void awaitResult(Future<?> future, int taskNo) throws InterruptedException, ExecutionException{
System.out.println("result : " + future.get());
JButton b = buttons.get(taskNo);
b.setEnabled(false);
}

It sounds like you want a CompletableFuture. You have a function which is a "supplier" which supplies a value. This is the function that's actually doing the work.
You then have a function which accepts that value whenever the worker is done.
This is all asynchronous, so everything else carries on regardless of the outcome.
class Main
{
private static Integer work() {
System.out.println("work");
return 3;
}
private static void done(Integer i) {
System.out.println("done " + i);
}
public static void main (String... args)
{
CompletableFuture.supplyAsync(Main::work)
.thenAccept(Main::done);
System.out.println("end of main");
}
}
Sample output:
end of main
work
done 3

Related

Last transformation not executed on CompletableFuture when completeExceptionally is called

I have following code:
public final class Start {
private static final CountDownLatch FINAL_THREAD = new CountDownLatch(1);
private static String getValue() {
System.out.println("Waiting...");
try {
Thread.sleep(Duration.ofSeconds(1).toMillis());
return "value";
} catch (InterruptedException e) {
return "interrupted";
}
}
private static void whenComplete(String value, Throwable ex) {
if (ex != null) {
System.out.println("whenComplete Ex: " + ex);
} else {
System.out.println("whenComplete Value: " + value);
}
}
private static String handle(String value, Throwable ex) {
if (ex != null) {
System.out.println("handle Ex: " + ex);
} else {
System.out.println("handle Value: " + value);
}
FINAL_THREAD.countDown();
return value;
}
private static String peek(String value) {
System.out.println("peek: " + value);
return value;
}
private static CompletableFuture<String> createRequest() {
System.out.println("Create....");
return CompletableFuture.supplyAsync(Start::getValue)
.thenApply(Start::peek)
.handle(Start::handle)
.whenComplete(Start::whenComplete);
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
createRequest().completeExceptionally(new RuntimeException("TEST"));
FINAL_THREAD.await();
}
}
When I execute it I get output like this:
> Task :Start.main()
Create....
Waiting...
peek: value
handle Value: value
BUILD SUCCESSFUL in 10s
I don't understand why Start::whenComplete is not called when both Start::peek and Start::handle are. If I switch handle with whenComplete then Start::handle will not be called, but Start::whenComplete will. I would expect that Start::whenComplete will be called with RuntimeExeception in this case, while other stages will be executed with value provided by Start::getValue.
I think the documentation of CompletableFuture covers this, but let's slowly get to it, as it is not that trivial. First we need to refactor slightly your code:
private static CompletableFuture<String> createRequest() {
System.out.println("Create....");
CompletableFuture<String> one = CompletableFuture.supplyAsync(Start::getValue);
CompletableFuture<String> two = one.thenApply(Start::peek);
CompletableFuture<String> three = two.handle(Start::handle);
CompletableFuture<String> four = three.whenComplete(Start::whenComplete);
return four;
}
And let's slightly change your main too:
public static void main(String[] args) {
CompletableFuture<String> f = createRequest();
boolean didI = f.completeExceptionally(new RuntimeException("TEST"));
System.out.println("have I completed it? : " + didI);
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(5));
}
Now let's carefully looks at this:
CompletableFuture<String> four = three.whenComplete(Start::whenComplete);
via the documentation of whenComplete:
Returns a new CompletionStage with the same result or exception as this stage, that executes the given action when this stage completes.
breaking it into smaller pieces:
Returns a new CompletionStage (four) with the same result or exception as this stage (three), that executes the given action (Start::whenComplete) when this stage (three) completes.
Who is supposed to execute Start::whenComplete? According to the documentation : four. When is it supposed to execute it? When three is completed.
According to your flow, before three is completed, you completeExceptionally your four. So when three is done, so is four - meaning it can't execute that Start::whenComplete (action); simply because it is already completed. Another way to think about it is that when your code reaches this line:
CompletableFuture<String> four = three.whenComplete(Start::whenComplete);
four is an un-completed future. It can be completed in two ways:
either when three is completed, thus triggering Start::whenComplete
externally (what you do with completeExceptionally)
Because you complete it externally before three is completed, it will not run that action.
If you chain an action to the future that you complete:
four.whenComplete(Start::whenComplete);
this is when you will see the desired output.

Can different threads access different independent methods of the same object at the same time in java?

Let's say we have 2 threads, and one object with 2 methods.
Thread 1 uses method1.
While method1 used by thread 1 is still running, can thread 2 use method2?
All of this assuming the object was not built with multithreading in mind (no synchronize or similar), and the methods do not access the same variables.
this code suggests that it is possible:
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class multithreadaccess {
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) throws IOException {
TestClass tc = new TestClass();
// invokes not sync method
FirstThreadRunnable ftr = new FirstThreadRunnable(tc);
Thread t1 = new Thread(ftr);
// invokes the sync method
SecondThreadRunnable str = new SecondThreadRunnable(tc);
Thread t2 = new Thread(str);
t1.start();
t2.start();
System.in.read();
}
public static class TestClass {
private int callCount = 0;
public void secondmethod() {
System.out.println("second method activated! Call number:" + " [" + callCount++ + "] from thread: "
+ Thread.currentThread().getId());
}
public void firstmethod() throws InterruptedException {
// Test with the sleep
System.out.println("starting first slow method from thread: " + Thread.currentThread().getId());
Thread.sleep(1000); // hold the monitor for 5sec
System.out.println("stopping first slow method! Call number:" + " [" + callCount++ + "] from thread: "
+ Thread.currentThread().getId());
// Test with spinning
/*
* System.out.println("MAKE IT SPIN! from thread: " +
* Thread.currentThread().getId()); boolean spin = true;
* while(spin){
*
* } System.out.println("IT STOPPED SPINNING! from thread: " +
* Thread.currentThread().getId()); }
*/
}
}
// invokes the not sync method
public static class FirstThreadRunnable implements Runnable {
TestClass tester = null;
public FirstThreadRunnable(TestClass tester) {
this.tester = tester;
}
#Override
public void run() {
try {
tester.firstmethod();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// invokes the sync method
public static class SecondThreadRunnable implements Runnable {
TestClass tester = null;
public SecondThreadRunnable(TestClass tester) {
this.tester = tester;
}
#Override
public void run() {
tester.secondmethod();
}
}
}
modified code from here
I do not understand how this is possible, though. I was always thinking an object is linear code. But this suggests that linear is only the code within the methods(As long as no variables are used by multiple methods)?
The problem of your code is the 2 methods firstmethod and secondmethod are not as "independent" as you thought, because both have callCount++.
This may create race condition, because both thread are updating that variable. You need to use AtomicInteger instead of int, then the code will work.
Edit:
In general, synchronization mechanism ("automatic blocking") is not enabled by default, because these operations are expensive and slow down the program. That's why Java provides synchronized keyword as well as threadsafe classes such has AtomicInteger to ensure proper access to shared variables and critical sections.

Editable queue of tasks running in background thread

I know this question was answered many times, but I'm struggling to understand how it works.
So in my application the user must be able to select items which will be added to a queue (displayed in a ListView using an ObservableList<Task>) and each item needs to be processed sequentially by an ExecutorService.
Also that queue should be editable (change the order and remove items from the list).
private void handleItemClicked(MouseEvent event) {
if (event.getClickCount() == 2) {
File item = listView.getSelectionModel().getSelectedItem();
Task<Void> task = createTask(item);
facade.getTaskQueueList().add(task); // this list is bound to a ListView, where it can be edited
Future result = executor.submit(task);
// where executor is an ExecutorService of which type?
try {
result.get();
} catch (Exception e) {
// ...
}
}
}
Tried it with executor = Executors.newFixedThreadPool(1) but I don't have control over the queue.
I read about ThreadPoolExecutor and queues, but I'm struggling to understand it as I'm quite new to Concurrency.
I need to run that method handleItemClicked in a background thread, so that the UI does not freeze, how can I do that the best way?
Summed up: How can I implement a queue of tasks, which is editable and sequentially processed by a background thread?
Please help me figure it out
EDIT
Using the SerialTaskQueue class from vanOekel helped me, now I want to bind the List of tasks to my ListView.
ListProperty<Runnable> listProperty = new SimpleListProperty<>();
listProperty.set(taskQueue.getTaskList()); // getTaskList() returns the LinkedList from SerialTaskQueue
queueListView.itemsProperty().bind(listProperty);
Obviously this doesn't work as it's expecting an ObservableList. There is an elegant way to do it?
The simplest solution I can think of is to maintain the task-list outside of the executor and use a callback to feed the executor the next task if it is available. Unfortunately, it involves synchronization on the task-list and an AtomicBoolean to indicate a task executing.
The callback is simply a Runnable that wraps the original task to run and then "calls back" to see if there is another task to execute, and if so, executes it using the (background) executor.
The synchronization is needed to keep the task-list in order and at a known state. The task-list can be modified by two threads at the same time: via the callback running in the executor's (background) thread and via handleItemClicked method executed via the UI foreground thread. This in turn means that it is never exactly known when the task-list is empty for example. To keep the task-list in order and at a known fixed state, synchronization of the task-list is needed.
This still leaves an ambiguous moment to decide when a task is ready for execution. This is where the AtomicBoolean comes in: a value set is always immediatly availabe and read by any other thread and the compareAndSet method will always ensure only one thread gets an "OK".
Combining the synchronization and the use of the AtomicBoolean allows the creation of one method with a "critical section" that can be called by both foreground- and background-threads at the same time to trigger the execution of a new task if possible. The code below is designed and setup in such a way that one such method (runNextTask) can exist. It is good practice to make the "critical section" in concurrent code as simple and explicit as possible (which, in turn, generally leads to an efficient "critical section").
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class SerialTaskQueue {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
// all operations on this list must be synchronized on the list itself.
SerialTaskQueue tq = new SerialTaskQueue(executor);
try {
// test running the tasks one by one
tq.add(new SleepSome(10L));
Thread.sleep(5L);
tq.add(new SleepSome(20L));
tq.add(new SleepSome(30L));
Thread.sleep(100L);
System.out.println("Queue size: " + tq.size()); // should be empty
tq.add(new SleepSome(10L));
Thread.sleep(100L);
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdownNow();
}
}
// all lookups and modifications to the list must be synchronized on the list.
private final List<Runnable> tasks = new LinkedList<Runnable>();
// atomic boolean used to ensure only 1 task is executed at any given time
private final AtomicBoolean executeNextTask = new AtomicBoolean(true);
private final Executor executor;
public SerialTaskQueue(Executor executor) {
this.executor = executor;
}
public void add(Runnable task) {
synchronized(tasks) { tasks.add(task); }
runNextTask();
}
private void runNextTask() {
// critical section that ensures one task is executed.
synchronized(tasks) {
if (!tasks.isEmpty()
&& executeNextTask.compareAndSet(true, false)) {
executor.execute(wrapTask(tasks.remove(0)));
}
}
}
private CallbackTask wrapTask(Runnable task) {
return new CallbackTask(task, new Runnable() {
#Override public void run() {
if (!executeNextTask.compareAndSet(false, true)) {
System.out.println("ERROR: programming error, the callback should always run in execute state.");
}
runNextTask();
}
});
}
public int size() {
synchronized(tasks) { return tasks.size(); }
}
public Runnable get(int index) {
synchronized(tasks) { return tasks.get(index); }
}
public Runnable remove(int index) {
synchronized(tasks) { return tasks.remove(index); }
}
// general callback-task, see https://stackoverflow.com/a/826283/3080094
static class CallbackTask implements Runnable {
private final Runnable task, callback;
public CallbackTask(Runnable task, Runnable callback) {
this.task = task;
this.callback = callback;
}
#Override public void run() {
try {
task.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
callback.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// task that just sleeps for a while
static class SleepSome implements Runnable {
static long startTime = System.currentTimeMillis();
private final long sleepTimeMs;
public SleepSome(long sleepTimeMs) {
this.sleepTimeMs = sleepTimeMs;
}
#Override public void run() {
try {
System.out.println(tdelta() + "Sleeping for " + sleepTimeMs + " ms.");
Thread.sleep(sleepTimeMs);
System.out.println(tdelta() + "Slept for " + sleepTimeMs + " ms.");
} catch (Exception e) {
e.printStackTrace();
}
}
private String tdelta() { return String.format("% 4d ", (System.currentTimeMillis() - startTime)); }
}
}
Update: if groups of tasks need to be executed serial, have a look at the adapted implementation here.

How to synchronize the threads in the time Java

I study a thread and trying make a timer using thread. To the main thread wrote a time
public class A {
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please, write the time in ms");
long time = Long.parseLong(reader.readLine());
B thread = new B();
int timer = 0;
try {
thread.start();
Thread.sleep(time);
timer=thread.stop();
}
catch(InterruptedException e) {
System.out.println("Oh....");
}
System.out.println("Result is "+timer);
}
}
and every millisecond program write a name of specific millisecond in child thread.
public class B implements Runnable {
private volatile boolean running=true;
private int timer=0;
Thread thread;
public B() {
thread = new Thread(this);
}
public void run() {
while (running) {
System.out.println(timer);
timer++;
try {
Thread.sleep(1);
}
catch(InterruptedException e) {
System.out.println("B");
}
}
}
public int stop() {
running = false;
return timer;
}
public void start() {
thread.start();
}
}
But when try with parameter 50 get the result 37. I want understand how to synchronize it in the time. Can you explain me how to do it correct?
When time is over just set the variable running to false,it will end the while loop and the child thread will also be finished.
So after below line, try to set running variable to false.(provide some setter method or may be in constructor argument)
Thread.sleep(time);
You are forgetting that all the statements other than Thread.sleep(1) also take time to execute. Most notably the System.out.println(timer): this is an I/O operation and whenever such an operation takes place, it usually sucks time (printing to screen makes the program wait for this blocking I/O operation to complete).
But I like to demonstrate a more subtle assumption: you also assume that when thread.start() returns, B.run() is executing. This is not the case, as is demonstrated in the following little program:
import java.util.concurrent.TimeUnit;
public class ThreadTimer implements Runnable {
public static void main(String[] args) {
ThreadTimer tt = new ThreadTimer();
long afterStart = 0L;
new Thread(tt).start();
afterStart = System.nanoTime();
println("After start: " + afterStart);
try {
Thread.sleep(100L);
} catch (Exception e) {
e.printStackTrace();
}
long deltaStart = tt.realStart - afterStart;
println("Delta start: " + deltaStart);
long deltaStartMs = TimeUnit.NANOSECONDS.toMillis(deltaStart);
println("Delta start ms.: " + deltaStartMs);
}
public long realStart;
#Override
public void run() {
realStart = System.nanoTime();
println("Real start : " + realStart);
}
private static void println(String msg) {
System.out.println(msg);
}
}
On my system this shows:
After start: 40062314666459
Real start : 40062314706827
Delta start: 40368
Delta start ms.: 0
Which means a little bit of time was lost. I'm sure that if you measure how long it takes to perform System.out.println(timer), you will see more little bits of time lost. All these little bits eventually add up to quite a chunk of time not accounted for.
On a final note: System.nanoTime() and System.currentTimeMillis() also take time to execute (it takes time to measure the time).

java callback functions in a multi threaded environment

In AJAX, suppose i submit a request asynchronously. When the reposne returns , it executes a callback function.
What is the best way to implement the same in a java multithreaded environment?
i.e Main thread creates a child thread and submits a task and then the child thread returns a callback function needs to be executed by the main thread.
Is this possible? In main thread I can do wait() and in child thread i can do notify() but in that case the main thread will wait until the child thread finishes.
But in AJAX the main thread continues its operation...that is what i want
You could use an ExecutorService to do tasks on the background and then use the methods of the Future you get back to wait for the result. For example:
class Main {
private static final ExecutorService es = Executors.newCachedThreadPool();
public static void main(final String... args) throws Throwable {
List<Future<Integer>> results = new ArrayList<>();
for (int i = 0; i < 10; i++) {
results.add(asyncSum(i, i*i));
}
// here, in the main thread, you can do whatever you want
// while the calculations are performed in background threads
// ...
// after the main thread finishes what it was doing, it
// can process the futures
for (final Future<Integer> result : results) {
System.out.println(result.get());
}
}
// this method launches a calculation on a worker thread and immediately
// returns a Future, which is a reference to the result of the calculation
// once it is completed
private static Future<Integer> asyncSum(final int a, final int b) {
return es.submit(new Callable<Integer>() {
#Override public Integer call() throws Exception {
return a + b;
}
});
}
}
In the example above, the main thread will block until the first computation is done, then print it. Then block until the second computation is done, then print it, etc.
If you wish to print the results as they become available (in an unspecified order), then you could use a CompletionService, and instead of having a list of results and iterating on it, you'd get your futures from the CompletionService itself through its .take() method, that blocks until a computation is finished, or .poll(), which returns a Future if there there are finished computations, or null if there are no computations finished -- this way your main thread will never block.
The following example uses a CompletionService. It shows a main thread that never blocks, uses background threads to do calculations and process the results as they become available:
class Main {
public static void main(String[] args) throws Throwable {
final ExecutorService es = Executors.newCachedThreadPool();
final CompletionService<Integer> cs = new ExecutorCompletionService<>(es);
submitSomeCalculations(cs);
while (true) {
doMainThreadWork();
processFinishedCalculations(cs);
}
}
private static void submitSomeCalculations(final CompletionService<Integer> cs) {
for (int i = 0; i < 10; i++) {
submitAsyncSum(cs, i, i * i);
}
}
private static void submitAsyncSum(final CompletionService<Integer> cs, final int a, final int b) {
cs.submit(new Callable<Integer>() {
#Override public Integer call() throws Exception {
Thread.sleep(100 + (long) (Math.random() * 900));
return a + b;
}
});
}
private static void processFinishedCalculations(final CompletionService<Integer> cs) throws ExecutionException, InterruptedException {
while (true) {
final Future<Integer> result = cs.poll();
if (result == null) {
System.out.println("> no finished results...");
break;
} else {
System.out.println("> result available: " + result.get());
}
}
}
static void doMainThreadWork() {
System.out.println("work from main thread...");
}
}

Categories

Resources