I'm trying to understand ConsumableFuture.
Basically, I supply a task to the ConsumableFuture and then put the worker thread running that task to sleep for 2 seconds. I expect the worker thread to resume execution after 2 seconds and return the result.
public class CompletableFutureDemo {
public static void main(String[] args) {
System.err.println("Application started");
CompletableFuture
.supplyAsync(()->work1())
.thenAccept(op-> System.out.println(op));
System.err.println("Application ended");
}
public static int work1() {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("work1 called");
return (int) (Math.random() * 100);
}
}
Output:
Application started
ForkJoinPool.commonPool-worker-1
Application ended
Why is the worker thread not resuming?
But if I remove the sleep statement from the worker thread, then I get the desired output.
Application started
ForkJoinPool.commonPool-worker-1
work1 called
Application ended
64
As #Slaw already pointed in the comment, the Main thread completes and exit the application when the work thread is sleeping, so you can call join to keep main thread waiting until work thread completes
System.err.println("Application started");
CompletableFuture
.supplyAsync(()->work1())
.thenAccept(op-> System.out.println(op)).join();
System.err.println("Application ended");
Output :
ForkJoinPool.commonPool-worker-3
Application started
work1 called
12
Application ended
Or you can keep main thread wait after completion of it work
System.err.println("Application started");
CompletableFuture<Void> completableFuture = CompletableFuture
.supplyAsync(()->work1())
.thenAccept(op-> System.out.println(op));
System.err.println("Application ended");
completableFuture.join();
Output :
ForkJoinPool.commonPool-worker-3
Application started
Application ended
work1 called
25
If you have multiple CompletableFuture objects then you can use allOf to wait until all tasks get completed (but in background every completable task will execute asynchronously)
CompletableFuture.allOf(completableFuture1,completableFuture1).join();
I achieved asynchronous operation as well as avoiding marking it as a daemon, by supplying my own instance of Executor. (Any flavour of Executor)
CompletableFuture
.supplyAsync(()->work1(), Executors.newFixedThreadPool(2))
.thenAccept(op-> System.out.println(op));
I think this would have avoided creating daemon threads, similar to what we have in ExecutorServices.
Thank you #Slaw for providing the information on the daemon thread. I would like to find out more why ForkJoin architecture would mark threads as a daemon by default.
Related
I wrote this simple testing program:
fun main() {
println("Main Start")
thread {
println("Thread Start")
Thread.sleep(3000)
println("Thread End")
}
println("Main End")
}
As I can see, the output is:
Main Start
Main End
Thread Start
Thread End
My expectation is that at-least the "Thread End" message will not be printed,
Cause that main function is ended and this main thread should be done running.
Is Kotlin process always waiting for threads to finish before done?
The thread that you have created is a non-daemon thread, and just like in Java, the JVM will not terminate until all the non-daemon thread are finished.
From Kotlin documentation one can read:
fun thread(
start: Boolean = true,
isDaemon: Boolean = false,
contextClassLoader: ClassLoader? = null,
name: String? = null,
priority: Int = -1,
block: () -> Unit ): Thread Creates a thread that runs the specified block of code.
Parameters
start - if true, the thread is immediately started.
isDaemon - if true, the thread is created as a daemon thread. The Java
Virtual Machine exits when the only threads running are all daemon
threads.
contextClassLoader - the class loader to use for loading classes and
resources in this thread.
name - the name of the thread.
priority - the priority of the thread.
Threads in Kotlin, by default, are non-daemon threads. This is why you can still see the output of the thread even thought the main thread have finished its execution. Set the isDaemon to true, and you will see the following output instead:
Main Start
Main End
Thread Start
I have written following program. Basically I am using executor framework to manage threads. I've also used a BlockingQueue and deliberately keeping it empty so that the thread remains in waiting state.
The below is the program:
package com.example.executors;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class ExecutorDemo {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService scheduledThreadPool = null;
BlockingQueue<Integer> bq = new LinkedBlockingQueue<>();
scheduledThreadPool = Executors.newSingleThreadScheduledExecutor((Runnable run) -> {
Thread t = Executors.defaultThreadFactory().newThread(run);
t.setDaemon(true);
t.setName("Worker-pool-" + Thread.currentThread().getName());
t.setUncaughtExceptionHandler(
(thread, e) -> System.out.println("thread is --> " + thread + "exception is --> " + e));
return t;
});
ScheduledFuture<?> f = scheduledThreadPool.scheduleAtFixedRate(() -> {
System.out.println("Inside thread.. working");
try {
bq.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, 2000, 30000, TimeUnit.MILLISECONDS);
System.out.println("f.isDone() ---> " + f.isDone());
Thread.sleep(100000000000L);
}
}
Once the program runs, main thread remains in TIMED_WAITING state, due to Thread.sleep(). In thread, which is managed by executor, i am making it to read an empty blocking queue, and this thread remain in WAITING state for ever. I wanted to see how does the thread dump looks in this scenario. I have captured it below:
"Worker-pool-main" #10 daemon prio=5 os_prio=31 tid=0x00007f7ef393d800 nid=0x5503 waiting on condition [0x000070000a3d8000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007955f7110> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at com.example.cs.executors.CSExecutorUnderstanding.lambda$2(CSExecutorUnderstanding.java:34)
at com.example.cs.executors.CSExecutorUnderstanding$$Lambda$2/1705736037.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
As expected thread Worker-pool-main remains in WAITING state. My doubt is on the thread dump.
As it is executor service which manages the life-cycle of thread in executor framework, then how this thread dump starts with Thread.run() method.
Shouldn't it be that first some portion of executor appearing and then Thread.run()
Basically , the doubt is: when life-cycle is managed by executor, then how come Thread.run() is appearing first and up the stack see portions of executors. Isn't executors starting these threads, so how they are appearing up in the stack?
When you start a new Thread, it will execute its run method on a completely new call stack. That is the entrypoint for the code in that Thread. It is completely decoupled from the thread that called start. The "parent" thread continues to run its own code on its own stack independently, and if either of the two threads crashes or completes it does not impact the other.
The only thing that shows up in a thread's stack frames is whatever gets called inside of run. You don't get to see who called run (the JVM did that). Unless of course, you confused start with run and called the run directly from your own code. Then there is no new thread involved at all.
Here, the thread is not created by your own code directly, but by the executor service. But that one does not do anything different, it also has to create threads by calling constructors and start them using start. The end result is the same.
What run usually does is delegate to a Runnable that has been set in its constructor. You see that here: The executor service has installed a ThreadPoolExecutor$Worker instance. This one contains all the code to be run on the new thread and control its interactions with the executor.
That ThreadPoolExecutor$Worker in turn will then call into its payload code, your application code, the tasks that have been submitted to the executor. In your case, that is com.example.cs.executors.CSExecutorUnderstanding$$Lambda$2/1705736037.
So, if i have understood this correctly, a thread goes into waiting state when we call wait on an object and it goes into blocked state when it is waiting for a lock on an object(like when trying to get into a synchronized block or method).
How does I/O-methods like read() put a Thread in a blocked state though? I understand WHY it has to be in a blocked state, waiting for data that it can read but i'm also interested in HOW. How does the JVM notify the thread that it can continue when data in the resource its trying to read, is available again?
It doesn't change the state of the thread to BLOCKED
public static void main(String[] args) throws IOException {
Thread main = Thread.currentThread();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(main + " is in "+main.getState()+" state");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new AssertionError(e);
}
}
}).start();
System.in.read();
}
prints
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
instead the OS doesn't return from the read until there is some data and the OS decides whether and when to context switch the thread/process.
How does the JVM notify the thread that it can continue when data in the resource its trying to read, is available again?
The OS wakes the thread when there is more data or the stream has been closed. The JVM doesn't get involved.
This depends on the native platform.
In POSIX, a call to read usually blocks until data is available, but there are many other reasons to return, such as an end-of-file was reached, the file descriptor was closed, the operation timed out or a signal interrupted the operation.
In Windows, the most closely related function is ReadFile.
The gory details, refering to Java 8 update 112 b15:
FileInputStream.read calls the native FileInputStream.read0, implemented natively through JNI in Java_java_io_FileInputStream_read0, which calls readSingle, which calls IO_Read.
In POSIX, IO_Read is defined as handleRead, which calls read. The RESTARTABLE macro loops while there's an error and the errno is EINTR.
In Windows, IO_Read is defined as handleRead, which calls ReadFile.
My Daemon create and runs a function on a different thread this function runs many other functions. I want to check before each function if the Daemon was closed and if not then i will perform the function.
How can i know if the Daemon was stopped?
Just like any other thread, you have to get the thread instance and then call:
thread.isAlive()
class Daemon extends Thread()
{
private boolean started;
public void Daemon() {
started = false;
}
public void run() {
started = true;
// rest of your code.
}
public boolean isStoped() {
return started && !isAlive();
}
}
Use isStoped() to know when your thread has been stoped. isAlive() alone is not enough because a thread which has not been started will return false.
When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.
If you don't know if the thread is daemon or not then use isDaemon,
isDaemon
public final boolean isDaemon()
Tests if this thread is a daemon thread.
Returns:
true if this thread is a daemon thread; false otherwise.
Then you can ask the Thread for its current status by calling:
Thread.State ts = thread.getState();
and you should get one of the follwing:
A thread state. A thread can be in one of the following states:
NEW
A thread that has not yet started is in this state.
RUNNABLE
A thread executing in the Java virtual machine is in this state.
BLOCKED
A thread that is blocked waiting for a monitor lock is in this state.
WAITING
A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
TIMED_WAITING
A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
TERMINATED
A thread that has exited is in this state.
Reference: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#isDaemon()
I just went through the source code of ThreadPoolExecutor found that it will interrupt all idle workers once the time is up to the set value of keepAliveTime and allowCoreThreadTimeOut is true.
It's a little strange to me it can only invoke the interrupt method when runState >= SHUTDOWN:
The code below is from the method getTask() of ThreadPoolExecutor.
Runnable getTask() {
...
if (workerCanExit()) {
if (runState >= SHUTDOWN) // Wake up others
interruptIdleWorkers();
return null;
}
}
Does that mean all the idle threads can only be interrupted when the runState >= SHUTDOWN (SHUTDOWN, STOP or TERMINATED)? That's to say they will be not interrupted when the state is RUNNING.
You are right. This getTask() method in the ThreadPoolExecutor is called on to gets the next task for a worker thread to run. This code block is only executed when the method call has not identified any Runnable task for execution. So, if nothing is found to execute, it must check for the shutdown state.
from java doc of workerCanExit()
Check whether a worker thread that fails to get a task can exit. We allow a worker thread to die if the pool is stopping, or the queue is empty, or there is at least one thread to handle possibly non-empty queue, even if core timeouts are allowed.
As an example, configure ThreadPoolExecutor as : corePoolSize=1, maxPoolSize=5, workQueueSize=1, keepAliveTime=60s, allowCoreThreadTimeOut=false.
When you offer 5 tasks(each task is time-consuming) concurrently, one of the 5 tasks will enter into workQueue, other 4 tasks will be handled immediately by 4 worker threads newly created almost at the same time.
At this time, the sum of worker threads is 4(workerThreadCount=4). Once one thread completes its task, it will be waiting on workQueue by invoking blocking method, workQueue.take() or workQueue.poll(keepAliveTime). As for which blocking method will be invoked is decided by the workerThreadCount.
For example(Hypothesis), at a time point, workerThread-0 is handling task-0; task-1 is staying in workQueue; workerThread-1 is handling task-2; workerThread-2 is handling task-3; workerThread-3 is handling task-4, and workerThreadCount==4.
workerThread-3 completes task-4, and this time [workerThreadCount==4] > [corePoolSize==1], it will get next task(task-1) from workQueue by workQueue.poll(keepAliveTime). Then, go on handling task-1, and this time workerThreadCount==4. The code segment of ThreadPoolExecutor.java as following:
while (task != null || (task = getTask()) != null) {
task.run();
}
private Runnable getTask() {
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take();
}
then workerThread-0 completes task-0, because of [workerThreadCount==4] > [corePoolSize==1], it still get next task from workQueue by workQueue.poll(keepAliveTime). But, this time workQueue is empty, so workerThread-0 will be blocked on it, and the state of workerThread-0 is TIMED_WAITING. Once keepAliveTime elapsed, workQueue.poll(keepAliveTime) will return null, next, workerThread-0 will return from Runnable.run(), and turn into TERMINATED. This time workerThreadCount==3.
then workerThread-1 completes task-2, it will return by the same way as workerThread-0. This time workerThreadCount==2.
then workerThread-3 completes task-1, it will return by the same way as workerThread-1. This time workerThreadCount==1.
then workerThread-2 completes task-3, but this time [workerThreadCount==1] not more than [corePoolSize==1], so it will be blocked when get the next task from workQueue by workQueue.take() until there is a available task in workQueue. And its state is WAITING.
NOTE : the source code comes from JDK8.
Exactly. A correct task(if interruptions are allowed) must checks itself for interrupted flag and terminate (i.e. return from run()).