> For the complete documentation index, see [llms.txt](https://www.pranaypourkar.co.in/the-programmers-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.pranaypourkar.co.in/the-programmers-guide/java/java-basics/parallelism-and-concurrency/thread-fundamentals/thread-context-switching.md).

# Thread Context Switching

## About

Context Switching is the process where the CPU switches from executing one thread (or process) to another. It involves **saving the current state** of the running thread and **loading the state** of the next thread.

In Java, context switching is a fundamental part of multithreading and concurrency, allowing multiple threads to **share CPU time efficiently**. However, excessive switching can introduce overhead, reducing performance.

## **How Context Switching Works ?**

When the CPU switches from one thread to another, it performs these steps:

1. **Save the execution state** of the current thread (Program Counter, Registers, Stack Pointer).
2. **Load the saved state** of the new thread that is to be executed.
3. **Resume execution** of the newly loaded thread from where it left off.

The entire process happens very fast (in milliseconds or microseconds), but it still introduces some overhead.

## **Why Does Context Switching Occur ?**

### **1. Preemptive Multitasking (Time-Slicing)**

* Java follows **preemptive scheduling**, meaning that the JVM scheduler **allocates a fixed time slice** for each thread.
* Once the time slice is over, the CPU switches to another thread, even if the previous one has not finished execution.

### **2. Thread Priority-Based Switching**

* The **JVM scheduler prioritizes high-priority threads**, causing context switching when a higher-priority thread becomes available.
* However, **thread priorities are not guaranteed** and depend on the OS-level thread scheduling policy.

### **3. Blocking Operations**

* If a thread **performs an I/O operation (file read, network call, database access, etc.)**, the OS may **pause it** and switch to another thread while waiting for the operation to complete.

### **4. Synchronization & Locks**

* When a thread **waits for a lock**, it is put in a **waiting state**, and the CPU switches to another thread that is ready to execute.

### **5. Manual Thread Sleep or Yield**

* Calling `Thread.sleep(time)` or `Thread.yield()` **forces the CPU to switch** to another thread voluntarily.

## **Example of Context Switching**

{% hint style="info" %}

* The output **does not follow a strict order** because of **context switching**.
* Each thread **runs independently**, and the JVM scheduler **decides when to switch threads**.
  {% endhint %}

```java
class Task extends Thread {
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + " is executing: " + i);
            try {
                Thread.sleep(100); // Simulate some work
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ContextSwitchingExample {
    public static void main(String[] args) {
        Thread t1 = new Task();
        Thread t2 = new Task();
        Thread t3 = new Task();

        t1.start();
        t2.start();
        t3.start();
        
        /* Output may vary
        Thread-0 is executing: 1
        Thread-1 is executing: 1
        Thread-2 is executing: 1
        Thread-0 is executing: 2
        Thread-1 is executing: 2
        Thread-2 is executing: 2
        ...
        */
    }
}
```

## **Types of Context Switching**

### **1. Process Context Switching**

* Happens when the OS switches between processes.
* **More expensive** due to separate memory space management.

### **2. Thread Context Switching**

* Happens when switching between threads of the **same process**.
* **Less expensive** than process switching, as threads share memory.

## **Performance Overhead of Context Switching**

Context switching is necessary for multitasking but introduces **performance costs**:

1. **CPU Overhead** – Saving and restoring registers, stack, and program counters.
2. **Cache Invalidation** – CPU cache may need to be reloaded when switching between threads.
3. **Locking Issues** – If multiple threads compete for locks, frequent switching may lead to **higher contention**.

## **Ways to Reduce Context Switching in Java**

### **1. Use Fewer Threads if Possible**

* Too many threads increase **CPU switching overhead**.
* Use **Thread Pools (`ExecutorService`)** to manage thread allocation efficiently.

```java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3); // Fixed thread pool of 3
        for (int i = 0; i < 5; i++) {
            executor.execute(new Task());
        }
        executor.shutdown();
    }
}
```

### **2. Use `Lock-Free` Data Structures**

* Avoid synchronized blocks when possible, as they increase thread waiting and switching.
* Use **concurrent collections** like `ConcurrentHashMap` instead of `synchronized Map`.

```java
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentExample {
    public static void main(String[] args) {
        ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
        map.put(1, "Thread Safe");
    }
}
```

### **3. Use `Thread.yield()` Wisely**

* `Thread.yield()` allows the JVM to switch to another thread **but does not guarantee switching**.

```java
class YieldExample extends Thread {
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println(Thread.currentThread().getName() + " running");
            Thread.yield();
        }
    }
}

public class YieldDemo {
    public static void main(String[] args) {
        YieldExample t1 = new YieldExample();
        YieldExample t2 = new YieldExample();

        t1.start();
        t2.start();
    }
}
```

### **4. Prefer `ReentrantLock` Over `synchronized`**

* `ReentrantLock` provides better control over locking mechanisms and can **reduce unnecessary context switching**.

```java
import java.util.concurrent.locks.ReentrantLock;

class ReentrantExample {
    private final ReentrantLock lock = new ReentrantLock();

    public void doWork() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " acquired lock.");
        } finally {
            lock.unlock();
        }
    }
}

public class ReentrantLockDemo {
    public static void main(String[] args) {
        ReentrantExample example = new ReentrantExample();
        Thread t1 = new Thread(example::doWork);
        Thread t2 = new Thread(example::doWork);
        t1.start();
        t2.start();
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://www.pranaypourkar.co.in/the-programmers-guide/java/java-basics/parallelism-and-concurrency/thread-fundamentals/thread-context-switching.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
