I would like to introduce Java Thread, as the main reason for choosing this topic is my current development work using Java. I often focus on writing basic syntax such as if, for, while, etc., but tend to overlook the aspect of MultiThread. This reflection is meant to document my progress. I hope to convey my insights and learning throughout the 30-day journey of mastering Java Thread. By the end of this period, I aim to have a solid understanding of Thread-related concepts, which will undoubtedly enhance my ability to write efficient and bug-free Thread-based programs.
On the first day, I would like to provide an overview of the fundamental concepts, specifically the relationship between Program, Process, and Thread:
Program:
A program is a set of instructions that have not yet been executed, or in other words, a collection of commands that can drive or command a computer. It can consist of instructions, human-readable code, compiled bytecode, or machine code.
Process:
When a program is executed, it generates an execution instance called a “Process,” which serves as a container for the program’s required space and resources during runtime. If the same program is executed ten times simultaneously, ten independent Processes will be created.
Thread:
On a single-core CPU, the CPU can indeed perform rapid context switching between different threads, but at any given moment, it can only execute one thread. This rapid context switching is controlled by the operating system’s scheduling mechanism, which ensures that each thread gets an opportunity to execute, thereby creating an illusion of concurrent processing of multiple tasks.
Memory Space:
Memory Space refers to the shared area that contains all the data and resources of a Process. All Threads under the same Process can access this Memory Space. However, different Processes have different Memory Spaces, and Processes cannot access each other’s Memory Space.
In writing multithreaded programs, there are primarily two approaches. One is to inherit the Thread
class, and the other is to implement the Runnable
interface.
Below is the implementation of a multithreaded program using inheritance of the Thread
:
import javax.swing.text.Document;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
// create two thread
MyThread thread1 = new MyThread("A");
MyThread thread2 = new MyThread("B");
// start the thread
thread1.start();
thread2.start();
}
static class MyThread extends Thread {
public String threadName;
public MyThread(String threadName){
this.threadName = threadName;
}
@Override
public void run() {
// Override the run() method, where the tasks for the Thread execution are defined.
for (int i = 0; i < 10; i++) {
System.out.println("Thread " + this.threadName + ": Count " + i);
}
}
}
}
Here’s an example of implementing a multithreaded program using the Runnable
interface:
// Multithreaded class implementing Runnable interface
public class MyRunnable implements Runnable {
public String threadName;
public MyRunnable(String threadName){
this.threadName = threadName;
}
public void run() {
for(int i = 0; i < 5; i ++){
System.out.println("Thread " + this.threadName + ": Count " + i);
}
}
}
// Creating and starting threads
public class Main {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
MyRunnable myRunnableA = new MyRunnable("A");
MyRunnable myRunnableB = new MyRunnable("B");
Thread thread1 = new Thread(myRunnableA);
Thread thread2 = new Thread(myRunnableB);
// Starting the threads
thread1.start();
thread2.start();
}
}