CompletableFuture is not getting executed. If I use the ExecutorService pool it works as expected but not with the common ForkJoinPool

TL;DR: The ForkJoinPool uses daemon threads, whereas the ExecutorService is using non-daemon threads. The latter keep the JVM alive; the former do not. Also, the main thread is a non-daemon thread and when you block it waiting for the CompletableFuture to complete it remains alive (thus keeping the JVM alive). Daemon vs Non-Daemon Threads A … Read more

How to properly use Java Executor?

ExecutorService ExecutorService executor=Executors.newFixedThreadPool(50); It is simple and easy to use. It hides low level details of ThreadPoolExecutor. Prefer this one when number of Callable/Runnable tasks are small in number and piling of tasks in unbounded queue does not increase memory & degrade the performance of the system. If you have CPU/Memory constraints, use ThreadPoolExecutor with … Read more

Synchronization vs Lock

If you’re simply locking an object, I’d prefer to use synchronized Example: Lock.acquire(); doSomethingNifty(); // Throws a NPE! Lock.release(); // Oh noes, we never release the lock! You have to explicitly do try{} finally{} everywhere. Whereas with synchronized, it’s super clear and impossible to get wrong: synchronized(myObject) { doSomethingNifty(); } That said, Locks may be … Read more