I couldn't find good explanation how JsonStreamWriter is using the provided ExecutionService.
In Java.
What is the best practice?
What is the pool size I need to set?
If I have multiple active JsonStreamWriters, do I need multiples ExecutionServices?
Solved! Go to Solution.
The ExecutorProvider
allows for more granular control over the threads used by JsonStreamWriter
. This feature is particularly useful for managing asynchronous operations in a more controlled and efficient way.
By using an ExecutorProvider
, you can customize the properties of the thread pool, such as:
This level of customization allows for better resource management tailored to your application's needs.
JsonStreamWriter
primarily uses threads from the ExecutorProvider
's pool for:
These are typically I/O-bound tasks, where the thread spends most of its time waiting for network responses.
Example
ExecutorProvider executorProvider = InstantiatingExecutorProvider.newBuilder()
.setExecutorThreadCount(4) // Number of threads
.setThreadFactory(r -> {
Thread thread = new Executors.defaultThreadFactory().newThread(r);
thread.setDaemon(true);
return thread;
})
.build();
JsonStreamWriter writer = JsonStreamWriter.newBuilder(tableId)
.setExecutorProvider(executorProvider)
.build();
Your question about the addCallback()
method potentially being evaluated after the append()
method completes is a valid concern in asynchronous programming.
In Java, ApiFutures.addCallback
attaches a callback to an ApiFuture
. If the future is already completed by the time addCallback
is called, the callback will be triggered immediately.
In your case, using MoreExecutors.directExecutor()
means the callback runs in the same thread that completed the future, potentially the network I/O thread.
Best Practice: Separate Executor for Callbacks
To avoid potential issues with the main thread, especially in GUI or service-heavy applications, it's safer to use a separate executor for the callbacks:
ExecutorService callbackExecutor = Executors.newCachedThreadPool();
ApiFutures.addCallback(future, new AppendCompleteCallback(this, appendContext), callbackExecutor);
This ensures callbacks are handled by a dedicated thread pool, preventing the main thread from being blocked and keeping your application responsive.