我正在尝试实施Akka并且有一个我无法获得的问题。
在Akka中,没有任何内容可以共享,但在下面的示例中,我想了解如何在Akka中处理它的共享资源
例如:我有一个历史表,其中包含每个客户的触发器列表。如果触发器在一天内被触发,则不应该在同一天为同一个客户再次触发另一个触发器。
此问题可以应用于共享资源的任何问题,另一个问题是代理密钥生成。
答案 0 :(得分:2)
你要分享的任何东西,把它放在一个演员里面。这使得它具有线程安全性,并且可以通过受控方式为所有人访问。
Scala示例:
object Messages {
case class AddCustomer(customerId: Int)
case class Trigger(customerId: Int)
case object ResetDay
}
class HistoryTable extends Actor {
def receive =
case Trigger(customerId) => {
context.child(customerId).get ! Trigger(customerId)
}
case AddCustomer(customerId) => {
context.actorOf(
Props(new Customer),
customerId) // Name of child
}
case ResetDay => {
context.children.foreach{
child => child ! ResetDay
}
}
}
}
class Customer extends Actor {
var triggered = false
def receive =
case Trigger(customerId) => {
if (!triggered) {
trigger()
triggered = true
}
}
case ResetDay => {
triggered = false
}
}
def trigger(): Unit = {
// Do something
}
}
编辑:添加了java版本:
public class Messages {
public static class AddCustomer {
private final int customerId;
public AddCustomer(int customerId) { this.customerId = customerId; }
pulic getCustomerId(): int { return customerId; }
}
public static class Trigger {
private final int customerId;
public Trigger(int customerId) { this.customerId = customerId; }
pulic getCustomerId(): int { return customerId; }
}
public static class ResetDay { }
}
public class HistoryTable extends UntypedActor {
public void onReceive(Object message) throws Exception {
if (message instanceof Trigger) {
int customerId = ((Trigger) message).customerId;
getContext().getChild(customerId).tell(
Trigger(customerId),
getSelf);
} else if (message instanceof AddCustomer) {
int customerId = ((AddCustomer) message).customerId;
getContext().actorOf(
Props.create(Customer.class),
customerId); // Name of child
} else if (message instanceof ResetDay) {
for (ActorRef child : getContext().getChildren()) {
child.tell(ResetDay, getSelf());
}
} else {
unhandled(message);
}
}
}
public class Customer extends UntypedActor {
private boolean triggered = false;
public void onReceive(Object message) throws Exception {
if (message instanceof Trigger) {
if (!triggered) {
trigger();
triggered = true;
}
} else if (message instanceof ResetDay) {
triggered = false;
} else {
unhandled(message);
}
}
private void trigger() {
// Do something
}
}