如何处理AKKA中的共享资源

时间:2015-04-14 08:35:34

标签: java akka

我正在尝试实施Akka并且有一个我无法获得的问题。

在Akka中,没有任何内容可以共享,但在下面的示例中,我想了解如何在Akka中处理它的共享资源

例如:我有一个历史表,其中包含每个客户的触发器列表。如果触发器在一天内被触发,则不应该在同一天为同一个客户再次触发另一个触发器。

此问题可以应用于共享资源的任何问题,另一个问题是代理密钥生成。

1 个答案:

答案 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
    }

}