Skip to content
Mayank Pant
Go back

Introduction to Multithreading

Understanding Procedure, Process, Processor and Thread

Before we understand what multithreading is, lets first understand Procedure, Process, Processor and Thread:

Let’s say we write a program, which has raw instructions, then that program is called as procedure. And, we need an internal flow of execution to execute that program, that internal flow of execution is what we call process. These processes are maintained by OS, but are generated by the hardware component, these hardware components are called processors.

Processor - Process - Procedure

For example:

What are Thread and Process then?

Thread and Process

Process:

When we have a java file and we run javac Test.java then it goes into compilation and generates a bytecode file that can be executed by the JVM. Next, when we run java Test, for the execution of bytecode file, then JVM starts a new Process for it.

Thread:

When a process is spun up, it has a single thread, often called as the main thread which is responsible for execution of that Process. But, Process has the ability to generate multiple threads inside it. So 1 Process can have multiple threads which can be used to perform tasks concurrently.

public class Test {
    public static void main(String[] args) {
        System.out.println("Thread name: " + Thread.currentThread().getName());
    }
}

Output: Thread name: Main


Going a little in depth of Process and Thread

When we run java Test and then java Test2, the OS creates a separate process for each execution. Each process runs its own JVM instance, and each JVM has its own heap, method area (metaspace), stacks, and other memory areas. These processes are isolated and do not share memory by default.

JVM process

All these are managed by the JVM.

Metaspace Metaspace contains:

Code Cache

Heap

Stack

CPU Registers

Program Counter

So the bytecode flow is:

Important Distinction:

So when a thread executes a method: First time: Reads bytecode from Metaspace → Interpreter converts → Executes After JIT compilation: Directly executes from Code Cache (bypasses Metaspace)

How much memory does each process get?

While creating the process using java Test command, a new JVM instance will get created and we can specify how much heap memory it should be allocated by the following command: java -Xms256m -Xmx2g Test Here -Xms<size> sets the initial heap size, above we generated 256MB. And -Xmx<size> will set the max heap size the process can have, above we set it to 2GB. If it tries to allocate more than this max memory then we will get OutOfMemoryError.

Understanding Java Execution: From Source Code to CPU

When you compile a Java file using javac Test.java, the compiler converts your human-readable Java code into machine-independent bytecode stored in Test.class. This bytecode can run on any platform that has a JVM.

Launching the JVM

Running java Test creates a new operating system process with a JVM instance running inside it. The JVM itself is a program written in C/C++ and compiled to native machine code for your specific platform.

Memory Organization

Each JVM process manages several memory areas:

Each thread within the process has its own private:

Execution Flow:

When the JVM starts, it loads the bytecode and creates the main thread to execute the main() method. Initially, the interpreter converts bytecode instructions to machine code on-the-fly and executes them immediately on the CPU. As execution continues, the JIT (Just-In-Time) compiler monitors the code. When it detects frequently executed methods (hot spots), it compiles that bytecode into optimized native machine code and caches it. Subsequent calls to these methods execute the pre-compiled version directly, resulting in significantly faster performance.

Multithreading

The main thread executes the main() method sequentially. If your code creates additional threads (using new Thread().start()), each new thread executes its assigned code independently and concurrently. All threads within the JVM process share the heap memory and data segment, but maintain their own stacks and execution state. This concurrent execution across multiple threads enables parallel processing, improved performance, and responsive applications—the essence of multithreading in Java.


Definition of Multithreading


Benefits and Challenges of Multithreading

Benefits:

Challenges:


Sources


Share this post on:

Previous Post
Introduction to RESTful Web Services
Next Post
Ways of making threads in Java