The Actor Model on the JVM: Part 1 - OOP and the Rise of Concurrency Challenges

February 17, 202523 min read16 views

Explore the evolution of Object-Oriented Programming and its challenges in concurrent programming, setting the stage for understanding the Actor Model as a solution.

The Actor Model on the JVM: Part 1 - OOP and the Rise of Concurrency Challenges
React to this article

The world of concurrent programming has evolved dramatically since the early days of computing. As our applications became more complex and our hardware more powerful with multiple cores, the traditional Object-Oriented Programming (OOP) paradigm began to show its limitations in handling concurrency effectively.

The Historical Context of OOP

Object-Oriented Programming didn't emerge overnight. Its roots trace back to the 1960s with Simula, which first introduced the concept of objects and classes. The paradigm was further developed in the 1970s with Smalltalk, which refined the messaging system between objects.

The real breakthrough came in the 1980s. Languages like C++, Java, and Python pulled OOP into mainstream programming. They promised code that was more modular, reusable, and easier to maintain by encapsulating data and behavior within objects.

IBM System 360 vs DEC PDP 11
Early mainframe computers like the IBM System 360 (1964) and DEC PDP-11 (1970) were primarily single-user, sequential processing machines. The evolution to concurrent programming began as these systems needed to handle multiple users and tasks simultaneously.

OOP's core principles seemed perfect for building complex systems. Encapsulation hides internal implementation details, inheritance enables reusing and extending existing code, polymorphism allows writing flexible code that works with different types, and abstraction simplifies complex systems through interfaces.

The Rise of Concurrency Challenges

As computing evolved, so did our needs. Single-threaded applications could no longer satisfy the performance requirements of modern systems. We needed applications that could:

  • Handle multiple users simultaneously
  • Process large datasets efficiently
  • Remain responsive while performing background tasks
  • Utilize multi-core processors effectively

This is where traditional OOP began to show its age. The fundamental challenge lies in shared mutable state – when multiple threads access and modify the same data concurrently.

The evolution of concurrency challenges: from simple sequential processing to complex multi-threaded problems, leading to the Actor Model as a solution.

The Threading Complexity Problem

Traditional thread management creates a web of complex synchronization issues:

// Traditional Java threading approach
public class BankAccount {
    private double balance;
 
    public synchronized void withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount; // Race condition without synchronization
        }
    }
 
    public synchronized void deposit(double amount) {
        balance += amount;
    }
}

While synchronized keywords help, they introduce their own problems: performance bottlenecks from thread blocking, deadlock risks when multiple locks are involved, complex debugging of race conditions, and scalability issues as contention increases.

Common Misconceptions About Concurrency

Many developers fall into these traps when approaching concurrent programming:

1. "Asynchronous = Parallel"

Asynchronous programming doesn't automatically guarantee parallelism. Async code can still run on a single thread, simply yielding control when waiting for I/O operations.

// This is asynchronous but not necessarily parallel
async function fetchData() {
  const result1 = await api.getData1();
  const result2 = await api.getData2(); // Still sequential!
  return { result1, result2 };
}

2. "Async Code is Always Faster"

Asynchronous operations aren't inherently faster. They are better at resource utilization. If you're CPU-bound rather than I/O-bound, async patterns might add complexity without adding speed.

3. "We Don't Need Threads Anymore"

Despite async/await patterns, threads remain fundamental to concurrent execution. Modern async runtimes still use thread pools under the hood to handle truly parallel work.

The Actor Model: A Different Approach

This brings us to the Actor Model – a paradigm that addresses these concurrency challenges by fundamentally rethinking how we structure concurrent applications.

Instead of sharing mutable state between threads, the Actor Model proposes a fundamentally different structure. Each actor has encapsulated state that it owns completely. Actors communicate only through message passing, maintaining strict isolation with no shared memory between them. And supervision provides built-in error handling and recovery mechanisms.

In upcoming parts of this series, we'll explore:

Why This Matters Today

Modern applications face unprecedented concurrency challenges. Microservices architectures require distributed coordination, real-time systems demand low-latency responses, IoT applications handle thousands of concurrent connections, and financial systems require both performance and correctness.

The Actor Model offers a proven approach to tackle these challenges, moving us away from the traditional thread-and-locks model toward a more scalable, fault-tolerant architecture.

Looking Forward

In the next article, we'll drill into the failure modes around shared mutable state. We'll use concrete scenarios where traditional OOP concurrency patterns break down. Then we'll examine why message passing changes the trade-off.

The journey from OOP to Actor-based concurrent programming isn't just about learning new syntax – it's about adopting a fundamentally different mental model for building scalable, resilient systems.


This article is part of our comprehensive series on concurrent programming patterns. Stay tuned for Part 2, where we'll explore the specific pitfalls of shared state in detail.

Further Reading

  • Hewitt, C., Bishop, P. & Steiger, R. (1973). "A Universal Modular ACTOR Formalism for Artificial Intelligence" — IJCAI. The original Actor Model paper
  • Agha, G. (1986). Actors: A Model of Concurrent Computation in Distributed Systems — MIT Press. The book that formalized the Actor Model
  • Reactive Manifesto — Foundational document for reactive systems built on Actor Model principles
  • Apache Pekko Documentation — The primary Actor Model framework discussed in this series
  • Goetz, B. et al. (2006). Java Concurrency in Practice — Addison-Wesley. Essential companion reading for understanding the concurrency challenges this series addresses
Actor Model on the JVMPart 1 of 3
Series Progress1 / 3
Arthur CostaA

Arthur Costa

Senior Full-Stack Engineer & Tech Lead

Senior Full-Stack Engineer with 8+ years in React, TypeScript, and Node.js. Expert in performance optimization and leading engineering teams.

View all articles →