Why does CompletableFuture.runAsync() not always submit to ForkJoinPool.commonPool()? - java

CompletableFuture.runAsync documentation states:
Returns a new CompletableFuture that is asynchronously completed by a task running in the ForkJoinPool.commonPool() after it runs the given action.
However, as far as I can tell, runAsync only submits a task to ForkJoinPool.commonPool() when ForkJoinPool.getCommonPoolParallelism() > 1. If not, it manually creates a new Thread for each submitted task.
Why exactly is this the case?

Yes, if ForkJoinPool parallelism level is less than 2, then new thread is created for every task here
All async methods without an explicit Executor argument are performed using the ForkJoinPool.commonPool() (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task).

Related

ExecutorService execute runnable in serial order

I'm using executor service with newSingleThreadExecutor to execute my Runnable task in serial order, however seems to be serial execution order is not guaranteed, as sometime tasks are executed in random order.
executorService = Executors.newSingleThreadExecutor();
executorService.submit(MyTask1);
executorService.submit(MyTask2);
MyTask performs some Asynchronous operation and send the result back to the class from where I'm executing the task.
though docs says, with newSingleThreadExecutor () tasks has to be executed serially,Im not able to find out what I'm missing here.any help would be appreciated.
Thanks
Since execution order is guaranteed to be sequential, you are problably not using a single thread executor in the code you are actually running.
As a work around, submit one task that does two things:
executorService.submit(() -> {MyTask1.run(); MyTask2.run();});
tl;dr
If the results you are watching arrive out-of-order are being produced asynchronously, then all is well. Async work is being done on its own separate timeline. By definition, the async work launched by task # 1 may not complete until long after tasks # 1, 2, & 3 are all done (for example).
Asynchronous means “don’t wait for me”
You mentioned:
MyTask performs some Asynchronous operation
Asynchronous execution means the calling code need not wait for the async operation to complete.
The calling code, your task submitted to the executor service, makes the request for async work to be done, and the task immediately continues. If that task has no further work, the task is complete. So the executor service can move on.
The executor service moves on. The executor service executes the second submitted task. Meanwhile, the async work requested above may not yet be done. Perhaps the async work is waiting on a resource such waiting for a call over the network to return, or the async work is waiting for a database query to execute. That, by definition of asynchronous, does not block the task submitted to the executor. The executor service is now running the 2nd submitted task, and may be a third or fourth, before, finally, your async work completes.
Feature, not a bug
In other words, a feature, not a bug. The ExecutorService returned by Executors.newSingleThreadExecutor() fulfilled its promise that “Tasks are guaranteed to execute sequentially”. The fact that as a by-product one of those tasks spins off async work does not change the fact that the tasks as submitted were indeed executed in their sequential order.

Intention for having CompletableFuture create separate thread for task when common pool does not support parallelism level >= 2

The Java doc for CompletableFuture states:
All async methods without an explicit Executor argument are performed using the ForkJoinPool.commonPool() (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task)
What is the reason for this decision of creating a thread for every single task? Why didn't they choose to create a pool with at least 2 workers instead, or why does the executor returned by commonPool() not have at least 2 workers?
Creating a thread for every task appears pretty inefficient to me.

How to have java executor with same thread?

For some proposes, I need to create an Executor which has always one same thread.
Executors.newFixedThreadPool(1);
Executors.newScheduledThreadPool(1);
Above examples create one thread pool but when work is done then the thread will be ended and again created a new one if a new task is passed to the executor.
So I figured out something like this:
new ThreadPoolExecutor(1,1,Long.MAX_VALUE, TimeUnit.DAYS, new LinkedBlockingQueue<>());
it seems that works but I have doubts if it's the right approach. Can someone show a better/correct way?
Executors.newSingleThreadExecutor();
From the documentation (emphasis mine):
Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.

Does completableFuture in Java 8 scale to multiple cores?

Lets say I have a single thread that calls bunch of methods that return completablefuture and say I add all of them to a list and in the end I do completablefutures.allof(list_size).join(). Now does the futures in the list can scale to multiple cores? other words are the futures scheduled into multiple cores to take advantage of parallelism?
CompletableFuture represents a task which is associated with some Executor. If you did not specify executor explicitly (for example, you used CompletableFuture.supplyAsync(Supplier) instead of CompletableFuture.supplyAsync(Supplier, Executor)), then common ForkJoinPool is used as executor. This pool could be obtained via ForkJoinPool.commonPool() and by default it creates as many threads as many hardware threads your system has (usually number of cores, double it if your cores support hyperthreading). So in general, yes, if you use all defaults, then multiple cores will be used for your completable futures.
CompletableFuture itself is not scheduled to a thread (or core). Tasks are. To achieve parallelism, you need to create multiple tasks. If your methods which return CompletableFuture submit tasks like
return CompletableFuture.supplyAsync(this::calculate);
then multiple tasks are started.
If they just create CompletableFuture like
return new CompletableFuture();
then no tasks are started and no parallelism present.
CompletableFuture objects created by CompletableFuture{handle, thenCombine, thenCompose, thenApply} are not connected to parallel tasks, so parallelism is not increased.
CompletableFuture objects created by CompletableFuture{handleAsync, thenCombineAsync, thenComposeAsync, thenApplyAsync} are connected to parallel tasks, but these tasks are executed strictly after the task corresponding to the this CompletableFuture object, so cannot increase parallelism.
Having a bunch of CompletableFutures doesn't tell you anything about how they will be completed.
There are two kind of completions:
Explicit, through cancel, complete, completeExceptionally, obtrudeException and obtrudeValue on an instance, or by obtainng a future with the completedFuture static method
Implicit, through executing a provided function, whether it returns normally or exceptionally, or through the completion of a previous future
For instance:
exceptionally completes normally without running the provided function if the previous future completes normally
Every other chaining method, except for handle and whenComplete and their *Async variations, complete exceptionally without running the provided function if the previous future, or any of the previous futures in the combining (*Both*, *Combine* and *Either*) methods, complete exceptionally
Otherwise, the future completes when the provided function runs and completes either normally or exceptionally
If the futures you have were created without a function or they're not chained to another future, or in other words, if they don't have a function associated, then they will only complete explicitly, and as such it makes no sense to say if this kind of completable future runs, much less if they may use multiple threads.
On the other hand, if the futures have a function, it depends on how they were created:
If they're all independent and use the ForkJoinPool.commonPool() (or a cached thread pool or similar) as the executor, then they will probably run in parallel, possibly using as many active threads as the number of cores
If they all have a dependency on each other (except for one) or if the executor is single-threaded, then they'll run one at a time
Anything in between is valid, such as:
some futures may depend on each other, or on some other internal future you have no knowledge of
some futures may have been created with e.g. a fixed thread pool executor where you'll see a limited degree of concurrently running tasks
Invoking join does not tell a future to start running, it just waits for it to complete.
So, to finally answer your question:
If the future has a function associated, then it may already be running, it may or may not run its function depending on how it was chained and the completion of the previous future, and it may never run if it doesn't have a function or if it was completed before it had a chance to run its function
The futures that are already running or that will run do so:
On the provided executor when chained with the *Async methods or when created with the *Async static methods that take an executor
On the ForkJoinPool.commonPool() when chained with the *Async methods or when created with the *Async static methods that don't take an executor
On the same thread as where the future they depend on is completed when chained without the *Async methods in case the future is not yet complete
On the current thread if the future they depend on is already completed when chained without the *Async methods
In my opinion, the explicit completion methods should have been segregated to a e.g. CompletionSource interface and have a e.g. CompletableFutureSource class that implements it and provides a future, much like .NET's relation between a TaskCompletionSource and its Task.
As things are now, most probably you can tamper with the completable futures you have by completing them in a way not originally intended. For this reason, you should not use a CompletableFuture after you expose it publicly; it's your API user's CompletableFuture from then on.

How to use Thread Pool concept in Java?

I am creating a http proxy server in java. I have a class named Handler which is responsible for processing the requests and responses coming and going from web browser and to web server respectively. I have also another class named Copy which copies the inputStream object to outputStream object . Both these classes implement Runnable interface. I would like to use the concept of Thread pooling in my design, however i don't know how to go about that! Any hint or idea would be highly appreciated.
I suggest you look at Executor and ExecutorService. They add a lot of good stuff to make it easier to use Thread pools.
...
#Azad provided some good information and links. You should also buy and read the book Java Concurrency in Practice. (often abbreviated as JCiP) Note to stackoverflow big-wigs - how about some revenue link to Amazon???
Below is my brief summary of how to use and take advantage of ExecutorService with thread pools. Let's say you want 8 threads in the pool.
You can create one using the full featured constructors of ThreadPoolExecutor, e.g.
ExecutorService service = new ThreadPoolExecutor(8,8, more args here...);
or you can use the simpler but less customizable Executors factories, e.g.
ExecutorService service = Executors.newFixedThreadPool(8);
One advantage you immediately get is the ability to shutdown() or shutdownNow() the thread pool, and to check this status via isShutdown() or isTerminated().
If you don't care much about the Runnable you wish to run, or they are very well written, self-contained, never fail or log any errors appropriately, etc... you can call
execute(Runnable r);
If you do care about either the result (say, it calculates pi or downloads an image from a webpage) and/or you care if there was an Exception, you should use one of the submit methods that returns a Future. That allows you, at some time in the future, check if the task isDone() and to retrieve the result via get(). If there was an Exception, get() will throw it (wrapped in an ExecutionException). Note - even of your Future doesn't "return" anything (it is of type Void) it may still be good practice to call get() (ignoring the void result) to test for an Exception.
However, this checking the Future is a bit of chicken and egg problem. The whole point of a thread pool is to submit tasks without blocking. But Future.get() blocks, and Future.isDone() begs the questions of which thread is calling it, and what it does if it isn't done - do you sleep() and block?
If you are submitting a known chunk of related of tasks simultaneously, e.g., you are performing some big mathematical calculation like a matrix multiply that can be done in parallel, and there is no particular advantage to obtaining partial results, you can call invokeAll(). The calling thread will then block until all the tasks are complete, when you can call Future.get() on all the Futures.
What if the tasks are more disjointed, or you really want to use the partial results? Use ExecutorCompletionService, which wraps an ExecutorService. As tasks get completed, they are added to a queue. This makes it easy for a single thread to poll and remove events from the queue. JCiP has a great example of an web page app that downloads all the images in parallel, and renders them as soon as they become available for responsiveness.
I hope below will help you:,
class Executor
An object that executes submitted Runnable tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. An Executor is normally used instead of explicitly creating threads. For example, rather than invoking new Thread(new(RunnableTask())).start() for each of a set of tasks, you might use:
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
...
class ScheduledThreadPoolExecutor
A ThreadPoolExecutor that can additionally schedule commands to run after a given delay, or to execute periodically. This class is preferable to Timer when multiple worker threads are needed, or when the additional flexibility or capabilities of ThreadPoolExecutor (which this class extends) are required.
Delayed tasks execute no sooner than they are enabled, but without any real-time guarantees about when, after they are enabled, they will commence. Tasks scheduled for exactly the same execution time are enabled in first-in-first-out (FIFO) order of submission.
and
Interface ExecutorService
An Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.
An ExecutorService can be shut down, which will cause it to stop accepting new tasks. After being shut down, the executor will eventually terminate, at which point no tasks are actively executing, no tasks are awaiting execution, and no new tasks can be submitted.
Edited:
you can find example to use Executor and ExecutorService herehereand here Question will be useful for you.

Categories

Resources