Skip to content

Latest commit

 

History

History
332 lines (216 loc) · 5.87 KB

File metadata and controls

332 lines (216 loc) · 5.87 KB

Synchronous vs Asynchronous Programming

1. What Is Synchronous Programming?

In synchronous programming, tasks are executed one after another, in a strict sequence.

Each task must complete before the next task starts.

The executing thread waits (blocks) until the current operation finishes.


Core Characteristics of Synchronous Programming

  • Sequential execution
  • Blocking in nature
  • Simple control flow
  • Easy to reason about
  • Poor resource utilization for slow operations

Simple Example (Synchronous Execution)

public class SyncExample {
    public static void main(String[] args) {
        System.out.println("Task 1 started");
        slowOperation();
        System.out.println("Task 2 started");
    }

    static void slowOperation() {
        try {
            Thread.sleep(3000); // simulating delay
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Execution Flow

Task 1 started
(wait 3 seconds)
Task 2 started

The program halts execution until slowOperation() completes.


Problems with Synchronous Programming

  • CPU stays idle during I/O wait

  • Poor scalability

  • Slow response time

  • Not suitable for:

    • Network calls
    • File I/O
    • Database queries
    • UI applications
    • High-traffic servers

2. What Is Asynchronous Programming?

In asynchronous programming, tasks are initiated, but execution does not wait for completion.

The task runs in the background, and the result is handled later.

The main thread continues execution without blocking.


Core Characteristics of Asynchronous Programming

  • Non-blocking execution
  • Better CPU utilization
  • Improved performance and responsiveness
  • Requires callbacks, futures, or promises
  • Slightly more complex control flow

Simple Example (Asynchronous Execution)

ExecutorService executor = Executors.newSingleThreadExecutor();

System.out.println("Task 1 started");

executor.submit(() -> {
    Thread.sleep(3000);
    System.out.println("Async Task completed");
    return null;
});

System.out.println("Task 2 started");
executor.shutdown();

Execution Flow

Task 1 started
Task 2 started
(wait 3 seconds)
Async Task completed

Main thread does not wait for the background task.


3. Blocking vs Non-Blocking (Key Concept)

3.1 Blocking (Synchronous)

future.get(); // blocks thread
  • Thread waits
  • CPU idle
  • Simple but inefficient

3.2 Non-Blocking (Asynchronous)

future.thenAccept(result -> System.out.println(result));
  • Thread continues execution
  • CPU stays productive
  • Better performance

4. Synchronous vs Asynchronous

Synchronous Model

Task A → Finish → Task B → Finish → Task C

Asynchronous Model

Task A → Task B → Task C
          ↘
        Async Task (runs independently)

5. Java Perspective

5.1 Synchronous Programming in Java

Examples:

  • Normal method calls
  • File I/O (traditional)
  • JDBC (blocking calls)
  • Thread.sleep()
int result = compute(); // blocking

5.2 Asynchronous Programming in Java

Examples:

  • Thread
  • ExecutorService
  • Future
  • CompletableFuture
  • Reactive APIs
CompletableFuture
    .supplyAsync(() -> compute())
    .thenAccept(result -> System.out.println(result));

6. Real-World Analogy

Synchronous Analogy

You order food and stand at the counter until it’s ready.

You can’t do anything else while waiting.


Asynchronous Analogy

You order food, get a token, and do other work. You’re notified when food is ready.

This is how modern servers work.


7. Performance and Scalability Impact

Synchronous Systems

  • One thread per request
  • Threads blocked during I/O
  • Poor scalability
  • High memory usage

Asynchronous Systems

  • Threads reused efficiently
  • Non-blocking I/O
  • Handles more requests with fewer threads
  • High scalability

8. Common Use Cases

When to Use Synchronous Programming

  • Simple scripts
  • CPU-bound tasks
  • Small applications
  • Linear business logic
  • Easy debugging required

When to Use Asynchronous Programming

  • Network calls
  • REST APIs
  • Database operations
  • File uploads/downloads
  • Microservices
  • High-traffic backend systems
  • UI applications

9. Comparison Table

Aspect Synchronous Asynchronous
Execution Sequential Concurrent
Blocking Yes No
Thread usage Inefficient Efficient
Complexity Low Medium–High
Scalability Poor Excellent
Performance Lower Higher
Debugging Easier Harder

10. Common Misconceptions

  • Asynchronous ≠ Multithreading (Async can use threads, but concept is about non-blocking)

  • Asynchronous ≠ Parallel (Async tasks may not run at the same time)


11. Interview Questions

Q1. What is synchronous programming?

Execution where each task waits for the previous task to finish.


Q2. What is asynchronous programming?

Execution where tasks run independently without blocking the main thread.


Q3. Is asynchronous programming always multithreaded?

No. It focuses on non-blocking execution, not thread count.


Q4. Why is async better for I/O operations?

Because it prevents threads from blocking during wait time.


Q5. Which is easier to debug?

Synchronous programming.


Key Takeaways

  • Synchronous programming is simple but blocking

  • Asynchronous programming is non-blocking and scalable

  • Async improves CPU utilization and throughput

  • Modern backend systems rely heavily on async models

  • Java supports async via ExecutorService, Future, and CompletableFuture