Basic Terms in Multithreading
To understand the terms of multithreading, we must have knowledge about concurrency, processes, and threads.
Concurrency
The concurrency stands for performing multiple tasks at the same time. In the process communication, the operating system permits the process to communicate with each other. Process communication indicates that some event has occurred or data is being transferred from one process to another. There are generally two models for concurrent programming Process Communication. They are as follows:
- Shared memory model
- Message passing model
Shared memory Model: The concurrent modules interact with each other by reading and writing shared objects in shared memory.

In the diagram, the shared memory can be accessed by Process1 and Process2
The shared memory is the memory that can be accessed by multiple processes simultaneously. The model is made in a way so that the processes can communicate with each other. Mostly, Windows operating systems use shared memory. Memory communication is faster on the shared memory model than the message-passing model on the same machine. It is necessary to ensure that processes using shared memory space are not allowed to write to the same memory location. The shared memory model may create problems such as synchronization and memory protection that need to be addressed.
Message passing Model: In this model, the concurrent modules interact with each other by sending messages through a communication channel. Modules send messages and are queued to handle incoming messages.

In the above diagram, both the processes process1 and process2 can access the message queue and retrieve data.
The messages are stored in the message queue until their recipient retrieves the messages. For inter-process communication, the operating system uses the message queue to communicate between the processes. Comparatively, the shared memory model is much easier to use and implement than the message-passing model.
Because the connection setup takes time, the message passing model has slower communication than the shared memory model.
Processes and Threads in the concurrency models:
Shared-memory and message-passing models are about how concurrent modules communicate with each other. Processes and threads are the two different techniques used in the concurrent modules.
Process: A process is a running program that takes place in memory. It takes a new memory that cannot be shared. The process is not able to access the memory or objects of any other process. By default, the process is ready for message- passing model as the process communicates with each other via message-passing.
Thread: Many threads in the process run the same program and share the same memory. Because all the threads share the memory in the process so we can say Threads are automatically ready for the shared memory model.
Important terms of Multithreading:
Some essential terms that are used for multithreading are as follows:
- Main thread
- Daemon Thread
- Start method
- Run method
Java provides built-in support for multithreaded programming. It contains two or more parts that can be run concurrently. Each part of the program is called a thread, and it defines a separate path of execution.
JVM creates two types of default Threads by calling start() method automatically. First is the Main Thread, and the second is Daemon Threads.
Flow Diagram:

The Main Thread
Whenever we start a Java program, there is a thread that begins running immediately. This thread is the main thread of our program, which is executed at the beginning of the program.
Some points about the main thread:
- All the child threads will be created from the main thread.
- The main thread must be finished its execution in the last because it performs various shutdown actions.
- For each program, the Main thread is created by JVM (Java Virtual machine). The Main thread first identifies the existence of the main() method. Then the rest of the threads are executed, which is declared in the main() method.
When our program is started, the main thread is created automatically. We can obtain a reference of the main thread by calling the method currentThread(), which is a public static member of the Thread. We can control it just like any other thread once we have a reference to the main thread.
Example:
public class ThreadDemo { public static void main(String args[]) { Thread t = Thread.currentThread(); System.out.println("Current thread: " + t); // change the name of the thread t.setName("My Thread"); System.out.println("After name change: " + t); try { for(int n = 5; n > 0; n--) { System.out.println(n); Thread.sleep(1000); } } catch (InterruptedException e) { System.out.println("Main thread interrupted"); } } }
Output:

The Daemon Thread:
This thread is generally run for the background tasks such as garbage collection, checking spelling grammar, etc.
The points about Daemon thread:
- JVM does not care whether Daemon thread is running or not; if the tasks of all the user threads are finished, it will exit from the program.
- Whenever all user threads finish their execution, JVM terminates itself.
- It is a low priority thread.
- By default, any thread always is the non-daemon thread.
- It is also known as the secondary thread.
Example:
public class ThreadDemo extends Thread { public ThreadDemo(String name) { super(name); } public void run() { //checking whether the thread is Daemon or not. if(Thread.currentThread().isDaemon()) { System.out.println(getName()+ "is Daemon thread"); } else { System.out.println(getName()+"is user thread"); } } public static void main(String args[]) { ThreadDemo t1=new ThreadDemo("ThreadA"); ThreadDemo t2=new ThreadDemo("ThreadB"); ThreadDemo t3=new ThreadDemo("ThreadC"); //setting user thread t1 to Daemon. //it should be before starting the thread. t1.setDaemon(true); t1.start(); t2.start(); //setting user thread t3 to Daemon. t3.setDaemon(true); t3.start(); } }
Output:

The start() method
We can create the Thread by two ways either extending Thread class or implementing Runnable interface. In both methods, we override the run () method, but we start a thread by calling the start () method. If we call run () method directly, it will not create a new thread.
Activities that happen when a start() method is called:
- The thread will move into the Runnable state.
- The arguments are evaluated, and the parameters are initialized.
- The new stack is created for new thread and associate the thread with that stack.
- From start() ,run() method is called by JVM.
Example1:
In the below example, whenever a program calls the start() method, a new thread is created, and then the run() method is executed.
public class ThreadDemo extends Thread { public void run() { try { //displaying the thread that is running. System.out.println("Current Thread name "+ Thread.currentThread().getName()); System.out.println("run() method called"); } catch(Exception e) { e.printStackTrace(); } } public static void main(String args[]) { ThreadDemo t3= new ThreadDemo(); //run() is called using start() t3.start(); } }
Output:

Explanation:
When we call start() method of our thread class instance, a new thread is created with default name Thread-0 and then run() method is called and everything inside it is executed on the newly created thread.
Example 2:
We cannot call the start() method twice. It throws a RunTimeException.
public class ThreadDemo extends Thread { public void run() { try { //displaying the thread that is running. System.out.println("Current Thread name "+ Thread.currentThread().getName()); System.out.println(" run() method called"); } catch(Exception e) { e.printStackTrace(); } } public static void main(String args[]) { ThreadDemo t3= new ThreadDemo(); //start calls twice. t3.start(); t3.start(); } }
Output:

Explanation:
As we are calling the start() method twice, it is throwing the exception as IllegalStateException .
The run method:
Features:
The run() method is the entry point of the thread execution. We can call run() method multiple times.
- We have to pass the object of the Runnable interface implemented class in the constructor of the Thread so that the overridden run() of the Runnable class will run via the start method.
- We can execute the overridden run() method of the Thread extended class via the start method.
Example 1:
Instead of using the start() method, the run() method can be called directly.
public class ThreadDemo extends Thread { public void run() { try { //displaying the thread that is running. System.out.println("Current Thread name "+ Thread.currentThread().getName()); System.out.println("run() method called"); } catch(Exception e) { e.printStackTrace(); } } public static void main(String args[]) { ThreadDemo t3= new ThreadDemo(); //run() is called directly without using start() t3.run(); } }
Output:

Explanation:
When the run() method calls of our class, no new thread is created and the run() method is executed on the current thread i.e. main thread . Hence no multithreading took place. Here the run() method is called as a normal function call.
Example 2:
We can call the run() method multiple times, as it is just a normal method calling.
public class ThreadDemo extends Thread { public void run() { try { //displaying the thread that is running. System.out.println("Current Thread name "+ Thread.currentThread().getName()); System.out.println(" run() method called"); } catch(Exception e) { e.printStackTrace(); } } public static void main(String args[]) { ThreadDemo t3= new ThreadDemo(); //run calls twice. t3.run(); t3.run(); } }
Output:

Explanation:
As we are calling the run() method twice, it does not raise any exception and it is executed twice as expected but on the main thread itself.
Can we call the run() method directly to start a new thread?
No, we cannot directly call run() method to start a new thread. We need to call the start() method to create a new thread. If we call the run method directly, and it will not create a new thread, it will be in the same stack as main. There will not exist the multithreading.
What is the difference between start() and run() method?
start() | run() |
It creates a new thread, after that the run() method can be executed. | If we directly call the run() method, no new thread is created, and it will execute on the calling thread itself. |
It cannot call more than one time. Otherwise, it will throw IllegalStateException. | Multiple invocations are possible. |
It is defined in the Thread class. | It is defined in the Runnable interface and also in the Thread class and must be overridden in the implementing class. |