1. Actor 编程简介
Actor 模型是一种并发编程模型,强调 消息传递,避免了传统共享内存并发带来的数据竞争问题。在 Actor 模型中:
- Actor 是计算的基本单元,它们封装状态并异步处理消息。
- 无锁并发,所有交互都通过消息传递完成,避免了线程同步问题。
- Actor 之间相互隔离,每个 Actor 只能通过消息影响其他 Actor,不会直接共享状态。
Java 语言本身不内置 Actor 模型,但可以使用 Akka、Quasar、Vert.x 等框架实现。
2. Akka Actor(最常用的 Java Actor 库)
2.1 Akka Actor 基本概念
Akka 是 JVM 生态中的流行 Actor 框架,提供了:
- Actor:处理消息的计算单元
- ActorSystem:管理 Actor 生命周期
- Props:用于创建 Actor
- Message Passing:Actors 之间通过
tell()
或ask()
传递消息
2.2 Akka Actor 依赖
在 pom.xml
添加 Akka 依赖:
<dependencies>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor-typed_2.13</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
2.3 创建 Akka Actor
import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.*;
public class HelloActor extends AbstractBehavior<HelloActor.SayHello> {
public static class SayHello {
public final String name;
public SayHello(String name) {
this.name = name;
}
}
private HelloActor(ActorContext<SayHello> context) {
super(context);
}
public static Behavior<SayHello> create() {
return Behaviors.setup(HelloActor::new);
}
@Override
public Receive<SayHello> createReceive() {
return newReceiveBuilder()
.onMessage(SayHello.class, this::onSayHello)
.build();
}
private Behavior<SayHello> onSayHello(SayHello message) {
System.out.println("Hello, " + message.name + "!");
return this;
}
}
📌 说明:
createReceive()
定义了如何处理SayHello
消息。onSayHello()
处理SayHello
并输出消息。
2.4 启动 ActorSystem
import akka.actor.typed.ActorSystem;
public class Main {
public static void main(String[] args) {
ActorSystem<HelloActor.SayHello> system =
ActorSystem.create(HelloActor.create(), "HelloSystem");
system.tell(new HelloActor.SayHello("Alice"));
system.tell(new HelloActor.SayHello("Bob"));
try { Thread.sleep(1000); } catch (InterruptedException ignored) {}
system.terminate();
}
}
📌 说明:
ActorSystem
启动 Actor,并发送SayHello
消息。tell()
是异步的,Actor 处理消息后继续执行。
3. 复杂 Actor 示例
以下示例模拟银行账户系统,Actor 处理存取款操作,并返回余额。
3.1 定义消息
public interface BankMessage {}
public class Deposit implements BankMessage {
public final int amount;
public Deposit(int amount) { this.amount = amount; }
}
public class Withdraw implements BankMessage {
public final int amount;
public Withdraw(int amount) { this.amount = amount; }
}
public class CheckBalance implements BankMessage {}
3.2 账户 Actor
import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.*;
public class BankAccount extends AbstractBehavior<BankMessage> {
private int balance = 0;
private BankAccount(ActorContext<BankMessage> context) {
super(context);
}
public static Behavior<BankMessage> create() {
return Behaviors.setup(BankAccount::new);
}
@Override
public Receive<BankMessage> createReceive() {
return newReceiveBuilder()
.onMessage(Deposit.class, this::onDeposit)
.onMessage(Withdraw.class, this::onWithdraw)
.onMessage(CheckBalance.class, this::onCheckBalance)
.build();
}
private Behavior<BankMessage> onDeposit(Deposit deposit) {
balance += deposit.amount;
System.out.println("Deposited: " + deposit.amount + ", New Balance: " + balance);
return this;
}
private Behavior<BankMessage> onWithdraw(Withdraw withdraw) {
if (balance >= withdraw.amount) {
balance -= withdraw.amount;
System.out.println("Withdrew: " + withdraw.amount + ", New Balance: " + balance);
} else {
System.out.println("Insufficient funds!");
}
return this;
}
private Behavior<BankMessage> onCheckBalance(CheckBalance checkBalance) {
System.out.println("Current Balance: " + balance);
return this;
}
}
3.3 运行账户 Actor
import akka.actor.typed.ActorSystem;
public class BankMain {
public static void main(String[] args) {
ActorSystem<BankMessage> bankAccount = ActorSystem.create(BankAccount.create(), "BankSystem");
bankAccount.tell(new Deposit(100));
bankAccount.tell(new Withdraw(30));
bankAccount.tell(new CheckBalance());
bankAccount.tell(new Withdraw(100));
try { Thread.sleep(1000); } catch (InterruptedException ignored) {}
bankAccount.terminate();
}
}
📌 说明:
- 账户 Actor 处理存取款请求,保证线程安全。
- 无锁并发,多个 Actor 可同时处理不同账户事务。
4. Actor 编程的优势
传统线程模型 | Actor 模型 |
---|---|
共享变量,需加锁 | 无共享状态,消息传递 |
容易发生死锁 | 无需锁,避免死锁 |
线程管理复杂 | ActorSystem 统一管理 |
调试复杂 | Actor 逻辑清晰,模块化 |
适用场景
✅ 高并发(如 Web 服务器、聊天应用)
✅ 分布式系统(如微服务、游戏服务器)
✅ 事件驱动(如日志处理、消息队列)
5. 其他 Actor 框架
5.1 Quasar(轻量级协程 Actor)
Quasar 提供 Fiber
(类似 Go 协程),适用于超高并发场景:
Actor<Object, String> actor = new Actor<>((msg) -> "Hello " + msg);
String reply = actor.send("Akka");
System.out.println(reply); // 输出 "Hello Akka"
适用于 高吞吐场景,但不如 Akka 成熟。
5.2 Vert.x(异步事件驱动)
Vert.x 采用 EventBus
消息传递:
eventBus.send("address", "Hello", reply -> {
System.out.println("Received: " + reply.result().body());
});
适用于 微服务、Web 后端。
6. 总结
- Akka 是 Java 最主流的 Actor 框架,适合构建并发和分布式系统。
- Actor 通过消息传递,避免共享状态和锁竞争,提高并发性。
- 适用于高并发、分布式、事件驱动应用,如 Web 服务器、金融系统、游戏服务器等。