Let us consider following is our thread:
public class HeavyWorkRunnable implements Runnable {
#Override
public void run() {
System.out.println("Doing heavy processing - START "+Thread.currentThread().getName());
try {
doDBProcessing();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Doing heavy processing - END "+Thread.currentThread().getName());
}
private void doDBProcessing() throws InterruptedException {
// TODO
}
}
And the main method:
public class ThreadRunExample {
public static void main(String[] args){
Thread t1 = new Thread(new HeavyWorkRunnable(), "t1");
Thread t2 = new Thread(new HeavyWorkRunnable(), "t2");
System.out.println("Starting Runnable threads");
t1.start();
t2.start();
System.out.println("Doing main heavy processing - START "+Thread.currentThread().getName());
System.out.println("Runnable Threads has been started");
}
}
Now the outputs are different at different run times. For example:
Output1:
Starting Runnable threads
Doing main heavy processing - START main
Doing heavy processing - START t1
Doing heavy processing - START t2
Doing heavy processing - END t2
Runnable Threads has been started
Doing heavy processing - END t1
Output2:
Starting Runnable threads
Doing main heavy processing - START main
Runnable Threads has been started
Doing heavy processing - START t1
Doing heavy processing - END t1
Doing heavy processing - START t2
Doing heavy processing - END t2
As per my understanding of thread:
1. Only a single thread can run at a time.
2. The system chooses threads randomly to run if priorities are not set.
So, the system should complete the tasks of 'main' thread, then run either t1 or t2. If so, then the output should always contain:
Starting Runnable threads
Doing main heavy processing - START main
Runnable Threads has been started
as the first three lines.
I'm not getting what I've missed in my understanding.
The thing is: varies between Operating Systems and their processing queues.
This is a lengthy topic, but long story short:
When the three threads are on the system queue, the OS let one of them run only a fraction of time (called quantum), and then pushes it to the queue to let other threads run, and so on, to have an illusion of multitasking in single processor-single core architectures. For this, each execution will be different for a myriad of reasons.
If you really want to dive into this topic, just start here link
Only one thread can run at a given time in a single processor, that is true. But the Java Virtual Machine contains a component which is called the Thread Scheduler. This component do choose which thread goes into the processor and which one gets out.
When you start a thread, it will enter the runnable state. When the thread scheduler have a slot for processing time, it will pick one of all the runnable threads (at random if they all have the same priority). The chosen one enters the running state for a few milli seconds before the Thread Scheduler interrupts the processing and places the thread back into runnable state.
A thread is consequently not guaranteed to finish its job before going out of the processor.
When you are experiencing with threads, you should consider that all threads that you have started can run concurrently, at the exact same time, so there is no guaranteed ordering.
What you may want to check is how to make a thread wait on other threads (using the Object.wait() method), but that's far beyond this answer.
If you need to dive into threading in Java, you should consider a specific training or google for online ressources, because this is not obvious at all.
First Let me clear your understanding that
Only one thread can run at a given time its true but only for single core processor not for multi cores.
Now Main method is nothing but internally a Thread. Now Threading Scheduling and Time Slicing depends on the OS. So, When you run your program Main method still its in Time Slice and hence System.out.println("Doing main heavy processing - START "+Thread.currentThread().getName()); statement is executed and than furthermore statements.
If you want to change your Output than you have to remove your Main Thread From Time Slice of OS.
So,after t2.start(); use Thread.sleep(1000) and you can check that your either t1 or t2 thread will get Scheduler and going for execution.
Related
This is a beginner question regarding multithreading in Java.
As per my understanding when multiple (user)threads are created to run the program or application, then there is no concept of Parent and Child threads. They are both independent user threads.
So, if the main thread finishes execution then another thread(Thread2) will still continue its execution because it will not be killed by the JVM until the Thread2's thread of execution is completed (https://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html, https://stackoverflow.com/a/9651919/6700081)
Then why am I not seeing the logs from the .log() being printed by Thread2 when the Main thread exits in the below code:
#Test
public void parentMainThreadAndChildThreadTest_WithSpringWebFlux() throws InterruptedException {
Flux<Long> infiniteFlux = Flux.interval(Duration.ofMillis(100));
infiniteFlux.subscribe((element) -> System.out.println("Value is:::" +element));
Thread.sleep(3000); //Main thread sleeps for 3 seconds
}
I see that if I increase the main thread's life by putting it to sleep then I can see the system out statements. But why aren't they displayed when the main thread is finished even though the Thread2 is still running asynchronously?
The test method is executed by the Main thread's thread of execution so what happens to the Thread2 after main thread finishes in this case?
if the main thread finishes execution then another thread(Thread2) will still continue its execution
this is true only for normal threads. Threads for thread pools usually are configured as daemon threads, which are forced to stop when all normal threads are finished.
In your case,
(element) -> System.out.println("Value is:::" +element)
is executed on a daemon thread taken from a reactor's thread pool.
I'm reading the book Oracle Certified Professional Java SE 7 Programmer Exams 1Z0-804 and 1Z0-805. One of the question asks the output of this code
class ThreadTest {
public static void main(String []args) throws InterruptedException {
Thread t1 = new Thread() {
public void run() { System.out.print("t1 "); }
};
Thread t2 = new Thread() {
public void run() { System.out.print("t2 "); }
};
t1.start();
t1.sleep(5000);
t2.start();
t2.sleep(5000);
System.out.println("main ");
}
}
The book says that it will always output t1 t2 main because TIMED_WAITING state can be only reach from RUNNABLE state.
But I was thinking that a thread can exit a RUNNABLE state without having executed a single instruction.
The doc says:
A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.
Is the answer of the book correct? And is it possible to exit the RUNNABLE state without having executed a single instruction?
I don't believe the book is correct, but for different reasons.
First off let's deal with your question directly. The only way to change out of RUNNABLE state is by executing an instruction which results in its state changing. This instruction might call a method (which happens to be synchronized and the thread then waits for a lock in BLOCKED) or return from the run() method (causing the thread to become TERMINATED). But these state changes always happen because the thread has done something to change its own state.
Edit - Just to elaberate on this; the method public void run() {} contains precisely one instruction: return. The thread must execute the return to get from RUNNABLE to TERMINATED.
The book is wrong (sort of). In "normal cases" 5 seconds is easily long enough to kick off a thread. But there is nothing synchronizing the threads and so nothing forcing the threads to do things in any particular order.
The the flow is:
The main thread kicks off t1.
The main thread then goes to sleep for 5 seconds. You would hope that 5 seconds is long enough for the OS to start a thread, but there is no guarantee that it will. If the OS is currently under attack from a fork bomb it might not have the resources to start the new thread.
The main thread then kicks off t2. If the OS is all clogged up and t1 hasn't started yet, there's no guarantee that t2 will not start (execute some code) first.
The main thread then goes to sleep for 5 seconds.
The main thread then prints "main ". Again if the OS is clogged up, this might actually happen before t1 or t2 start.
Never rely on a sequence of multiple threads without using synchronization!
I have code like this:
public class OtherClass {
// OtherClass
public synchronized static void firstMethod() {
System.out.println("FIRST METHOD");
}
public synchronized static void secondMethod() {
System.out.println("SECOND METHOD");
// In actual code I would have try catch for this but here I just didn't
// include it
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class MainClass {
// main method of MainClass
public static void main(String args[]) {
Thread firstThread = new Thread() {
public void run() {
while (true) {
OtherClass.firstMethod();
}
}
};
Thread secondThread = new Thread() {
public void run() {
while (true) {
OtherClass.secondMethod();
}
}
};
secondThread.start();
firstThread.start();
}
}
The reason I start the 2nd thread first is because I want the secondMethod of OtherClass to execute first. I should see "FIRST METHOD" and "SECOND METHOD" in the console output every 5 seconds. The reason being is that since Thread.sleep does not relinquish the lock, for 5 seconds the first thread doesn't have access to the first method because the second thread has got a lock on the class while it's in the second method which tells the thread to sleep for 5 seconds. But I get very unexpected results. All I get in the console output is "SECOND METHOD" every 5 seconds. The firstMethod isn't called.
Ignoring compilation problems in your code.
That's just coincidence. The thread scheduler simply decides to continue executing the second thread which reacquires the lock too fast.
Run it long enough (or with a shorter sleep time for faster results) and you'll see the other method get invoked.
The reason I start the 2nd thread first is because I want the secondMethod of OtherClass to execute first.
That's not how threads work. That's not what threads are for. Threads provide no guarantees of what happens before what else except where you provide explicit synchronization between them; And generally speaking, the more synchronization you use, the less you will benefit from having multiple threads.
In your example, you have explicit synchronization that prevents any concurrent executions of firstMethod() and secondMethod(), but you have nothing that guarantees which one will run first, and which one will run second. Chances are, that main() will terminate before either of them runs. At that point, it's up to the scheduler to pick which one will run when. There is no requirement that it start them in the same order that your code called their start() methods.
Your example may be educational, but it also is an example of when not to use threads. Your synchronization is very heavy handed. Your program basically does two things, firstMethod() and secondMethod(), and the synchronization insures that they can not be overlapped. In production software, if you have two tasks that must not overlap, then it'll simplify your program's logic if they are always performed by the same thread.
All I get in the console output is "SECOND METHOD" every 5 seconds. The firstMethod isn't called.
Your question was edited before I got to see it, so I don't know whether you're talking about the original version, or the fixed version. But in any case:
The synchronization in your program does not guarantee that the two threads take turns. All it does is prevent them both from printing at the same time.
Each of your threads runs a loop that grabs the lock, prints something, releases the lock, and then immediately tries to grab the lock again. When a running thread releases a lock, and then immediately tries to get it again, the chances are it will succeed. It doesn't matter that some other thread was waiting for the lock. The OS doesn't know what your program is trying to accomplish, but it does know that it can make more efficient use of the CPU by letting a thread continue to run instead of blocking it and un-blocking some other thread.
You will need to use some additional synchronization to make the threads take turns, but like I said, in a real program, the more synchronization you use, the less benefit there is to using threads.
Your processor won't execute your Threads at the same time; it'll run your second thread every time bevore your first thread.
The behaviour is clear: Your processor executes your second thread. Then, the processor executes your first thread and sees that it is locked by your second thread. After 5 seconds, your second thread is called again. It makes the output, releases the lock and locks it again. If your first thread is called again, it is locked again.
To fix this, add Thread.yield() at the end of your while. This will make the processor call the first thread before continuing to execute your second thread (the first thread won't be the only one that is called, it just removes your second thread 1 time from it's execution). Then your first thread gets the lock, waits 5 seconds, outputs and calls Thread.yield(); then your second thread gets the lock again and so on.
What you are experiencing is thread starvation. In your case, one thread is being blocked indefinitely waiting to enter a synchronization block because the other thread is constantly allowed access.
To overcome thread starvation you need to employ some sort of fairness locking. Locks that are conceived as fair give priority to the threads waiting the longest to acquire said lock. Such a locking strategy eliminates the possibility of thread starvation and insures all waiting threads will be executed at some time.
Fairness locking in Java can easily be accomplished by using a ReentrantLock with a fairness parameter set to true.
So I am trying to work with threads for a game I am making. I am very new to the subject so I may not understand correctly. My question is how does the currentThread() method work in the Thread class of the java API. The API says "Returns a reference to the currently executing thread object.", but as far as I understand multiple threads run at the same time. How is it possible to return only one executing thread?
The code that calls currentThread will be executing in one of the threads, not in all of them, so it can get that thread specifically.
Suppose you have list of instructions printed on a piece of paper. A person reads the instructions and performs them. The instructions are a program. The person is a thread. You could make many copies of the paper and pass them out to many people. If the instructions say something like, "slap yourself," yourself refers to whomever is reading that instruction from that paper. Likewise, Thread.currentThread() refers to the thread that is executing that call to currentThread().
When an instruction in your code is executed, it is executed within a specific thread. This is the thread returned by that method.
Obviously, if a specific method is executed by multiple threads, each execution might return a different value for Thread.currentThread().
You could try this short example to get a better idea of what is going on and in particular the fact that the 2 threads execute in parallel. You should see that t1 will run a few loop then t2 will do the same and back to t1 etc (you might need to increase the number of loops from 5 to a higher number depending on your machine):
public class TestThread {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread());
}
}
};
Thread t1 = new Thread(r, "t1");
Thread t2 = new Thread(r, "t2");
t1.start();
t2.start();
}
}
"The currently executing thread" means that the system scheduler gave some time to this thread to execute its code.
When writing a single threaded application, you can reason on your program like a series of instruction, each executed after the previous one is finished (this is a rough approximation, but conceptually compilator and processor try to simulate that and work as if this was really what was happening).
When you use multiple thread, each thread has its own series of instruction. A new thread when created is passed a entry point (a method), and will continue executing from them. Each thread is independent from the other thread in their execution (it will simply execute one instruction after the other), though they share memory and thus side-effect from one thread can affect another.
So for some code to be executed, it must be done in the context of one thread (there is one created by the operating system when your application start, that start its execution at the Main method). When the function currentThread is called, it is in one of those context.
The java runtime when creating a thread will store a reference to that Thread object in the thread context, and the currentThread will just lookup there and return the current thread.
At any given point in time, only one thread will be executing(live), so Thread.currentThread() returns the details of the currently executing Thread. e.g., Thread_name, priority, method_name.
Multiple threads are not running at the same time and there is thread switching between multiple threads. Processor can execute one task at a time so one thread at a a time executed. So we get the reference of currently running thread.
As currently executing thread while it encounters the call sleep() then thread moves immediately into sleeping stat.
Whereas for yield() thread moves into runnable state / ready state.
We can prevent a thread from execution by using any of the 3 methods of Thread class:
yield() method pauses the currently executing thread temporarily for giving a chance to the remaining waiting threads of the same priority or higher priority to execute. If there is no waiting thread or all the waiting threads have a lower priority then the same thread will continue its execution. The yielded thread when it will get the chance for execution is decided by the thread scheduler whose behavior is vendor dependent.
join() If any executing thread t1 calls join() on t2 (i.e. t2.join()) immediately t1 will enter into waiting state until t2 completes its execution.
sleep() Based on our requirement we can make a thread to be in sleeping state for a specified period of time (hope not much explanation required for our favorite method).
sleep() causes the thread to definitely stop executing for a given amount of time; if no other thread or process needs to be run, the CPU will be idle (and probably enter a power saving mode).
yield() basically means that the thread is not doing anything particularly important and if any other threads or processes need to be run, they should. Otherwise, the current thread will continue to run.
Sleep() causes the currently executing thread to sleep (temporarily cease execution).
Yield() causes the currently executing thread object to temporarily pause and allow other threads to execute.
Read [this] (Link Removed) for a good explanation of the topic.
Sleep causes thread to suspend itself for x milliseconds while yield suspends the thread and immediately moves it to the ready queue (the queue which the CPU uses to run threads).
Yield : will make thread to wait for the currently executing thread and the thread which has called yield() will attaches itself at the end of the thread execution. The thread which call yield() will be in Blocked state till its turn.
Sleep : will cause the thread to sleep in sleep mode for span of time mentioned in arguments.
Join : t1 and t2 are two threads , t2.join() is called then t1 enters into wait state until t2 completes execution. Then t1 will into runnable state then our specialist JVM thread scheduler will pick t1 based on criteria's.
Yield(): method will stop the currently executing thread and give a chance to another thread of same priority which are waiting in queue. If thier is no thread then current thread will continue to execute. CPU will never be in ideal state.
Sleep(): method will stop the thread for particular time (time will be given in milisecond). If this is single thread which is running then CPU will be in ideal state at that period of time.
Both are static menthod.
Yield: It is a hint (not guaranteed) to the scheduler that you have done enough and that some other thread of same priority might run and use the CPU.
Thread.sleep();
Sleep: It blocks the execution of that particular thread for a given time.
TimeUnit.MILLISECONDS.sleep(1000);
yield(): yield method is used to pause the execution of currently running process so that other waiting thread with the same priority will get CPU to execute.Threads with lower priority will not be executed on yield. if there is no waiting thread then this thread will start its execution.
join(): join method stops currently executing thread and wait for another to complete on which in calls the join method after that it will resume its own execution.
For detailed explanation, see this link.
One way to request the current thread to relinquish CPU so that other threads can get a chance to execute is to use yield in Java.
yield is a static method.
It doesn't say which other thread will get the CPU.
It is possible for the same thread to get back the CPU and start its execution again.
public class Solution9 {
public static void main(String[] args) {
yclass yy = new yclass ();
Thread t1= new Thread(yy);
t1.start();
for (int i = 0; i <3; i++) {
Thread.yield();
System.out.println("during yield control => " + Thread.currentThread().getName());
}
}
}
class yclass implements Runnable{
#Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("control => " + Thread.currentThread().getName());
}
}
}
sleep()causes the thread to definitely stop executing for a given amount of time; if no other thread or process needs to be run, the CPU will be idle (and probably enter a power saving mode).
yield()basically means that the thread is not doing anything particularly important and if any other threads or processes need to be run, they should. Otherwise, the current thread will continue to run.
sleep() causes the thread to definitely stop executing for a given amount of time; if no other thread or process needs to be run, the CPU will be idle (and probably enter a power saving mode).
yield() basically means that the thread is not doing anything particularly important and if any other threads or processes need to be run, they should. Otherwise, the current thread will continue to run.
Both methods are used to prevent thread execution.
But specifically,
sleep():
purpose:if a thread don't want to perform any operation for particular amount of time then we should go for sleep().for e.x. slide show .
yield():
purpose:if a thread wants to pause it's execution to give chance of execution to another waiting threads of same priority.thread which requires more execution time should call yield() in between execution.
Note:some platform may not provide proper support for yield() . because underlying system may not provide support for preemptive scheduling.moreover yield() is native method.