初始化Akka ActorRef,使其状态与前一个状态相同

nue99wik  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(165)

如何在AkkaActors之间共享balance的状态?
我知道如何使用 prop 初始化一个Actor,但是每当我创建一个Actor时,它就会用相同的值新建一个新的Actor。我可以使用同一个ActorRef两次吗?当我试图通过在for之外创建来重用同一个ActorRef时,它只会传递死信。

public static void main(String[] args) {
        ActorSystem system = ActorSystem.create("bank-system");
        ActorRef bankAccount;

        Random rnd = new Random();
        for (int i = 0; i < 10; i++) {
            int num;
            OptionalInt randomVal = rnd.ints(-1000, 1000).findFirst();
            if (randomVal.isPresent()) {
                num = randomVal.getAsInt();
            } else {
                num = i;
            }
            bankAccount = system.actorOf(BankAccount.props(100), "bankAccount-" + i);
            // Something not sending correctly
            if (num > 0) {
                bankAccount.tell(new DepositMessage(num), ActorRef.noSender());
            } else {
                bankAccount.tell(new WithdrawMessage(num), ActorRef.noSender());
            }
        }

        system.terminate();
    }

    public class BankAccount extends AbstractActor {
        private int balance;

        public BankAccount(int balance) {
            this.balance = balance;
            System.out.printf("Bank account initialised with £%d%n", balance);
        }

        public static Props props(int balance) {
            return Props.create(BankAccount.class, () -> new BankAccount(balance));
        }
    }
xzv2uavs

xzv2uavs1#

一般来说,参与者的意义在于它封装了自己的状态。它可以通过发送消息来“告诉”另一个参与者它的状态,但这与共享它的状态并不是一回事:到其他参与者处理消息时,不能保证发送参与者没有以某种方式更改其状态。
您可以在循环之外创建一个actor,并将结果ActorRef保存在一个变量中(甚至是一个集合,例如HashMap)。actor将在消息之间保持其状态。
但是,您的BankAccount代码并不处理任何DepositMessageWithdrawalMessage,因此这可能是您看到消息传递到死信的原因。
例如:

@Override
public Receive createReceive() {
    return receiveBuilder()
        .match(DepositMessage.class, dm -> {
            // Deposit never fails (assuming it's non-negative)
            System.out.printf("Depositing £%d%n", dm.getAmount());
            balance += dm.getAmount();
        })
        .match(WithdrawalMessage.class, wm -> {
            int amount = -wm.getAmount();
            if (amount > 0) {
                System.out.printf("Attempting to withdraw £%d%n", amount);
                if (amount <= balance) {
                    System.out.println("Successfully withdrew £%d%n", amount);
                    balance -= amount;
                } else {
                    System.out.println("Overdraft of £%d rejected%n", amount - balance);
                }
            }
        });
}

相关问题