Every Java program has at least one thread. The default main thread that executes the main method (usually public static void main(String args). A thread represents an independent path of code execution within a program. Many threads can run concurrently in a Java program; your app can create threads to perform time-intensive tasks and run it in the background. This allows the application to remain responsive to its users.
- [Narrator] You're probably wondering, what is this concept of a thread in Java? Every Java program has at least one thread. That thread represents the default main thread that executes the main method. Our main method is usually public static void main with some parameters inside the parentheses. A thread represents an independent path of code execution within a program. If we don't create any additional threads, the only thread in your program is the main thread, which is created automatically by the JVM.
So you might not even have realized it, but all your programs up unto this point, had at least one thread running. The nice thing in Java is that many threads can run concurrently in a single Java program. One of the biggest benefits of threads is that your application can create threads to perform time-intensive tasks and then run them in the background. This allows the application to remain responsive to its users. Once a thread is created, it executes code sequences that are encapsulated in objects that are known as runnables.
So each thread executes a runnable object. Threads are most commonly used for initiating an asynchronous task; where asynchronous means that it can run concurrently, at the same time, instead of sequentially. The program can initiate the task and then move on to another part of the program without waiting for the first task to finish. The opposite would be synchronous, which runs one task to completion and then starts the next task.
The JVM, the Java Virtual Machine, gives each thread its own private JVM stack, which is basically its own private area of memory. This prevents threads from interfering with each other. The stack holds local variables and partial results and it keeps track of the next instruction to be executed and plays a part in calling methods and handling return values. Java supports threads primarily through its java.lang.Thread class and java.lang.Runnable interface.
When a class is created, it is either a daemon or non-daemon thread. It's not what you think. It doesn't mean evil or good. A daemon thread is a thread that does not prevent the JVM from exiting when the program finishes but the thread is still running. By default, threads are created as non-daemon threads. An example of a daemon thread might be the Java garbage collection, which runs even after your program finishes. Since it is considered a daemon thread, it does not stop the JVM from exiting and it can continue to do its work.
In order to create a daemon thread, you can call setDaemon with an argument of true. The Java main method is a non-daemon thread, so the JVM continues to execute threads; including main, until either the exit method of the class runtime has been called, or all threads from this particular program that are not labelled as daemon threads have died. Okay, let's take a look at a diagram that illustrates the life of a thread. We start with a new thread. A new thread begins its life cycle in the new state.
The thread does not actually execute any task until the start command has been executed. Then it enters runnable. After a thread is started, the thread becomes runnable and the code in the run method is executed. A thread in this state is considered to be running it's task. Sometimes, a thread transitions to the waiting state, while the thread waits for another thread to perform a task. The thread transitions back to the runnable state only when another thread notifies or signals the waiting thread to continue executing.
Also, a runnable thread can enter the timed waiting state or the sleep state for a specified interval of time. A thread in this state transitions back to the runnable state when the time interval expires or the time has elapsed. And the last part of the life cycle is when the thread is terminated or is considered dead. A runnable thread enters the terminated state when it completes its task or otherwise terminates. There's a slight difference between putting a thread to sleep, and asking a thread to wait for another thread to be completed.
The sleep method is actually considered a static method. This static method performs the operation on the currently running thread. You can also use a method called current thread to get the currently running thread who is also a static method. The wait method has to actually be called upon an object. So you have to use a thread object to invoke the wait state. So this is a sample life-cycle of a thread. Again, you can have multiple threads in a single Java program.
- What is a thread?
- Creating threads
- Syncing threads
- Understanding concurrency
- Working with the Java locking framework