Any program may have several processes or instances. Each of these processes can be given either a single thread or several threads. In this lesson, we will practice multitasking/multiprocessing and learn further about threads and inter-thread synchronization.
A program or process is split up into two or more subprograms or processes that can be executed in parallel in multithreading. Most modern computers only have one processor, therefore in practice, the processor only does one task at a time. However, because the CPU flips between the processes so quickly, people mistakenly believe that they are all happening simultaneously.
When we run a typical program, it goes through a series of executions and then comes to an end. There is only ever one statement being executed at any given time. This is due to the fact that most applications have a single sequential flow of control.
A program with a single stream of control is analogous to a thread. It executes orders in order and has a start, middle, and end. In actuality, single-threaded programs may be used to describe any main program. There will be at least one thread in every application.
In Java, the smallest and lightest processing unit is called a single thread. A “Thread Class” is how Java implements threads. There are two different types of threads: daemon threads and user threads (daemon threads are used in the background when we want to clean the application). User threads are generated at the start of an application. Following that, we may generate a large number of user and daemon threads. The structure of a single thread is given below
Advantages of the single-threaded program:
Reduces application overhead because just one thread is running on the system.
Lowers the application’s maintenance expenses.
Java’s multithreading feature allows the CPU to be used to its fullest by running two or more threads concurrently. Applications using multiple threads execute two or more threads at once. Thus, it is sometimes referred to as concurrency in Java. Parallel lines connect one thread to the next. Because several threads share one memory space, memory is saved. Additionally, context switching across threads is quicker. The structure of the multithreaded program is given below:
Advantages of the multithreaded program:
Because threads are separate and we occasionally support several operations, users are not blocked.
Because each thread is autonomous, if one encounters an exception it won’t affect the others.
New: The thread is generated in this stage using the class “Thread”. Up until the thread is started by the application, it stays in this condition. It’s also referred to as the born thread.
Runnable: On this page, a start method is used to initiate the thread instance. The scheduler is given thread control to complete the program. The scheduler determines whether to execute the thread.
Running: The status changes to “running” when the thread begins to execute. One thread is chosen by the scheduler first from the thread pool, and it begins running in the application.
Waiting/Blocked: When a thread must wait, it is said to be in the waiting state. There is a requirement for thread synchronization because the program is operating numerous threads at once. As a result, one thread must wait while the other executes.
Dead: This is the thread’s condition after it has been shut off. The thread is now in its “running state,” and once it has finished processing, it will enter its “dead state.”
The program structure representing the life cycle of the thread is given below:
Single-threaded program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package ThreadExample;
class AThread extends Thread {
public void run() {
System.out.println("AThread : START");
for (int i = 0; i < 7; i++)
System.out.println("\tPart of Thread AThread : i = " + i);
System.out.println("AThread : EXIT");
}
}
public class SingleThread {
public static void main(String[] args) {
new AThread()
.start();
}
}
Output:
Multithreaded program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package ThreadExample;
class AThread extends Thread {
public void run() {
System.out.println("AThread : START");
for (int i = 0; i < 7; i++)
System.out.println("\tPart of Thread AThread : i = " + i);
System.out.println("AThread : EXIT");
}
}
class BThread extends Thread {
public void run() {
System.out.println("BThread : START");
for (int i = 0; i < 7; i++)
System.out.println("\tPart of Thread BThread : i = " + i);
System.out.println("BThread : EXIT");
}
}
class CThread extends Thread {
public void run() {
System.out.println("CThread : START");
for (int i = 0; i < 7; i++)
System.out.println("\tPart of Thread CThread : i = " + i);
System.out.println("CThread : EXIT");
}
}
public class SingleThread {
public static void main(String[] args) {
new AThread()
.start();
new BThread()
.start();
new CThread()
.start();
}
}
Output: