I have a small test using just two threads as follows:
import static java.lang.System.out;
#Test
public void testTwoSimpleThreads() {
doInParallelAsync(() -> {
out.println("First Ok");
},
() -> {
out.println("Second Ok");
});
}
private void doInParallelAsync(Runnable first, Runnable second) {
new Thread(() -> {
first.run();
}).start();
new Thread(() -> {
second.run();
}).start();
}
Sometimes the output will only include one of them before I introduced join() after they're started.
Two different outputs I encountered so far:
one
First Ok
Two
First Ok
Second Ok
I know the println() is synchronized and also I know the threads created by main thread are user threads in default and user threads will not exit until they finish.
Though I am using #Test, I tested it that they're non-daemon as expected.
non-daemon
is a daemon thread if and only if the creating thread is a daemon
And
The Java Virtual Machine continues to execute threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
UPDATED
Actually I know what the answers point out, I wonder why the output disappear?
Questions I need to ask:
The pipeline closed by the main thread?
Why? Is it because each pipeline is bond to one thread independently? Not shared? (that the pipeline won't be closed until the last thread finish just like the reference counting - the file will not be deleted until no one is using it)
The last question: is it controlled by JVM or dependent upon the OS?
It seems the pipeline is closed by the #Test I mentioned. Thank you, #meriton for pointing it out.
Conclusion
When I tried this method in an ordinary main(), and directly invoke System.exit(0); just right after the start(), the output is quite the same as that when using #Test.
When using #Test (Junit), the threads will not be waited. For more details, please check JUnit test not executing all threads created within the test and JUnit terminates child threads.
And here is an explanation from #Alex Lockwood which I personally prefer:
JUnit is a unit testing framework... as with the Android framework, it has a main thread from which it will call user-defined unit test methods. When a unit test returns, JUnit immediately invokes the next unit test method (or exits completely if there are no more unit test methods to call). JUnit doesn't know anything about the background threads you create/start, so you can't assume that it will sit around and wait for them to finish.
Might the test runner invoke System.exit() after all tests have run? Can you reproduce the partial output if you convert the test into an ordinary main() method?
(I'd try myself, but was unable to reproduce a partial output when running this as a JUnit test in eclipse)
... and no, System.out is a static field, and hence shared by all threads. Exiting the main thread does not close the stream.
Thats because you started them on a different thread and the main thread do not wait for child threads to complete and will close its execution immediately after last line.
So, by that time if Thread 1 is executed Output will be:
First Ok
If Thread 2 is executed:
Second Ok
And if by luck both got executed then
First Ok
Second Ok
or
Second Ok
First Ok
By providing join, you are asking main thread to wait for the child thread to be completed and hence both the outputs.
-- EDITED --
This doesn't mean that the child threads were terminated, they still completed their execution but you may not be able to see the results as outstream may have been closed or released by that time
If you execute the same command on Jshell, you will always get the second output, but sometimes it come in as another command, because as soon as main thread completes, Jshell moves to next command line:
Related
This question already has answers here:
Do java threads get deleted when they finish
(3 answers)
Closed 7 years ago.
I want to know if a thread in java closes itself when run method ends.
I mean, I have a new thread declaration:
new Thread(new SubmitDataOnBackground(handler.getIDValue(), data, this.context)).start();
And then, in SubmitDataOnBackground I have this run method:
public void run() {
SubmitDataHandler submit = new SubmitDataHandler(ID, data, this.context);
submit.buildAndSubmitData();
}
After buildandSubmitData finishes, does the thread close itself or I have to add any code somewhere?
I am not sure if I am leaving a new thread opened each time I call this method or it is ok.
My application is a server so it will never ends because it is active the whole time. I just want to know the amount of threads is not outnumbered because it just creates new ones without closing the others when finish.
Threads close themselves after the run method has been called. Read this for further information https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
EDIT: If you want to avoid this behaviour, I recommend using ThreadPools.
Yes, a thread finishes when run() method execution ends. You can read more on threads and concurency in general here
One tip here - when using multiple threads that are started and finished all the time, it is a good idea to use a thread pool. That is because creating a thread is quite a heavy operation.
Threads are terminated after finishing their jobs (when the execution of run() ends). If you want to check, use isAlive().
Yes, threads are terminated after finishing their specified jobs (sequence of instructions) in run() method.
However, the thread object that has been created still exists, allowing you call it again with Thread.start() to create a new Thread.
If you want to be sure that your thread run method ends before continuing doing something more, try to use the method Thread.join() in the same place where you are working with threads.
Read this for further information about that:
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#join%28%29
In order to actually make a Thread stop itself, the process is quite simple. All you need to do is simply let the run method run out and return.
public void run(){
// implement your code
// Just about to return and the Thread will then stop soon after
}
Note that the thread will not necessarily be declared finished immediately after the run method has finished, as the Java Virtual Machine (JVM) still needs to finish it off in the background, but it should terminate completely soon after.
In other words, when a normal Thread (also referred to as a user Thread) is created, it is expected that it will complete its work and not shut down permanetly. The JVM will not terminate until all user Threads have finished, or until a call is made to the System.exit() method, which terminates the JVM abruptly.
EDIT: System.exit() does not stop the JVM abruptly, it executes all the shutdown hooks first. Runtime.getRuntime().halt() stops the JVM without any further processing.
I have a slightly complicated test structure so bear with me,
I have a series of testng test cases and during each I collect some data about the test( not directly but using a library which I wrote). This library once it gets the data kicks off an analysis program on another thread and the main thread proceeds with executing the rest of the test. (I do this because the analysis is slightly time consuming and I don't want the main test to block).
At the end only a few analysis program threads are left but testng still shuts the test down and the data for the last few test cases could not be analysed.
I don't want a hardcoded sleep at the end. Is there a way I can direct TestNG to wait until any threads spawned by this test (directly or via associated libraries) finish?
You can in general do one of the following:
1) By making the main Thread wait for another Thread using
Thread.join();
2) Making the another Thread as Non Daemon or a user thread:link
Thread.setDaemon(false);
The Java Virtual Machine exits when the only threads running are all daemon threads.This method must be called before the thread is started.
For the below program different outputs are coming when running and debugging on eclipse.
public class MyClass implements Runnable {
public static void main (String[] args) throws Exception {
Thread t = new Thread(new MyClass());
t.start();
System.out.print("Started");
t.join();
System.out.print("Complete");
}
public void run() {
for (int i = 0; i < 4; i++) {
System.out.print(i);
}
}
}
When running this as java application the OUTPUT is
Started0123Complete
When checking in Debug Mode OUTPUT is
0123StartedComplete
Can someone help on this? is it because of two threads? main thread and the thread which starts with t.start().If yes then why main thread execution is taking more priority to complete first?
Thanks
The order in which the string "Started" and the integers are printed out is undefined by definition. After you call start, there is no guarantee that the code in the run method will be executed before or after any other statement that appears before the call to join. This is the nature of multithreaded applications.
The fact that you see a certain output in debug mode vs run mode is probably purely accidental and might change if you run your code many times or on different platforms/versions of the JVM. If you need deterministic order in this case, the only way you can achieve it is to print a string before calling start or introduce some other sort of semaphore to force the thread to wait for the main thread or viceversa.
It's coincidence. You can't control the thread scheduler.
However, in a debug environment, the debugger plugs into your code to inspect values and execution. This inspection increases the amount of work done per thread time slice.
For example, in a regular run, the main thread may only need 1 time slice to create the new thread object, start it, and print the Started message. Then a context switch would occur and the second thread would get a chance to work. In a debug run, the main thread would only have enough time to create the new thread object and start the corresponding thread. Then the context switch would occur and the other thread would do its thing.
It is not related to being in debug mode or not.
There is no guarantee of when this gets executed
System.out.print("Started"); //this is in the main thread
compared to
for (int i = 0; i < 4; i++) { // this is in the started thread
System.out.print(i);
}
It can even be
01Started23Complete
Yes, Its because of 2 threads But the output is unpredictable.
No, the main thread doesn't get high priority because its MAIN.
you can't say any particular interleaved execution in multithreads.
In Debug, my guess is you put a break point for main thread so it waits and in the mean time the other thread might have executed.
In both (Run / Debug) the mode output will be
Started0123Complete
You are seeing result 0123StartedComplete, because you must be having debug point inside main thread code, that’s why.
If you want to understand better, then move the run() method to inside MyClass and put debugger point inside run method now you will see it is printing as Started0123Complete.
Internally, Main Thread is creating subthread “t” and when t.start() is being called it is waiting to capture the monitor for thread execution (i.e. run()) and when you are adding debug statement in main thread, sub-thread is entering into monitor and run method is executing and once it completed, main thread is starting again.
In the below code what could be the predicted output?
public class Threads2 implements Runnable {
public void run()
{
System.out.println("run.");
throw new RuntimeException("Problem");
}
public static void main(String[] args)
{
Thread t = new Thread(new Threads2());
t.start();
System.out.println("End of method.");
}
}
The possible outcome given as the answers are:
End of method.
run.
java.lang.RuntimeException: Problem
OR
run.
java.lang.RuntimeException: Problem
End of method.
According to me only answer 2nd is possible, please help me to understand.
Both answers are possible. It's up to the thread scheduler to decide when instructions of concurrent threads are executed. The started thread and the main thread are run "in parallel", and the only guarantee is that the each thread's instructions are executed in sequence. But there could be any interleaving betwen the two sequences of operations.
You could also have the following, BTW.
run
end of method
java.lang.RuntimeException: Problem
To make an analogy, imagine you have a hurdle race, and you tell each runner to start the race, one at a time. Do you know which runner will come at each hurdle in first position? No, you don't. It depends on the speed of each runner. If the first runner to start is very slow, the last runner could come at the first hurdle before him. That's the same with threads. The scheduler assigns each running thread to a core, in any order he wants to, and for any time it decides. The only guarantee you have is that each thread will be executed some time.
t.start(); tells the system to start the thread - nothing says that the system has to actually give the thread execution time right away.
Another possibility is:
run.
End of method.
java.lang.RuntimeException: Problem
The execution will result in two threads, the main thread (the one running the main-method), and the thread created in the main method. Since you can't guarantee anything when it comes to the order that the threads will run, there are multiple orders that the code could run.
So lets call the main thread Thread1, and the created thread Thread2. The possibilties then are, after Thread2 has been started:
Thread1 gets the processor time first. ("End of method..." get printed first)
Thread2 gets the processor time first. ("run" get printed first)
and, there is actually a third possibility (i think):
Thread2 get the processor time and prints "run".
Thread2 gets interupted, and Thread1 takes over.
Thread1 prints "End of..."
Thread2 throws the exception.
First of all, note that the Exception's stack trace is usually printed to the stderr stream of the process, while you write to the stdout. Often stderr is redirected to stdout, but this is not required.
Another thing to consider is that the documentation doesn't state anything about the concurrent access of PrintStream#println(), so the output when two threads try to print at the same time is truly umpredictable.
Given that it doesn't make much sense to have the exception stack trace in the game (because it's another stream altogether), the problem is reduced to which between the main thread and the other one writes first. Not only this is up to the JVM scheduler, but also consider that the method is not synchronized, so it could even print an interleaved string (well, I don't think this will ever happen in reality, but this is what may happen).
I think your question is "why can the output of 'run' be printed after the exception is printed". They are in the same thread, and should execute in sequence, which should guarantee System.out.print("run"); execute first then throw new RuntimeException("Problem");is executed after that.
The problem here is those two lines of code uses different printing queue. System.out.print() use the standard output, while the error message caused by throw new RuntimeException("Problem");will go to the standard error output. So which message prints first not only depends on which line of code gets executed first, but also which output queue flushed to screen first.
If the second line of code is System.out.print("problem"); then 'problem' will always print after 'run' since they are using the same output queue
Java Thread can have begining,end and sequence,What does that mean?
I think all it means is that a thread executes a sequence of actions. It's expressing that concept pretty badly, to be honest.
In other words:
You create a Thread, ideally passing it a Runnable. (You can extend Thread instead and override its run method but that's generally frowned upon.)
You call start on it
The thread which called start continues executing the next statement in its program
The run method executes in the separate thread, independently of the thread that started it. The behaviour in here is what I believe is meant by the "sequence"
The new thread eventually ends due to one of the following conditions:
Its run method completes normally
Its run method completes with an exception
If it's a daemon thread, it can terminate as part of the JVM terminating due to all the non-daemon thread exiting