如何用AkkaActor模拟转账

博客介绍了并发问题的两种处理方法,多线程方法虽可让多个线程争夺共享资源,但存在破坏操作原子性和死锁风险;另一种是消息机制,AkkaActor基于此原理。还展示了用AkkaActor模拟转账过程的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于并发问题有两种处理方法,一种就是采用多线程方法;多个线程对共享的资源进行争夺,缺点在于破坏了操作的原子性以及潜在的死锁风险。

另一种思路就是消息机制,在要并发的对象中通过传递消息控制其操作,AkkaActor就是基于这一原理的工具。

下面试着用AkkaActor模拟上一篇文章中的转账过称。具体说明见注释。

package pers.machi.akkaconcurrent

import akka.actor.{Actor, ActorRef, ActorSystem, Props}

object AkkaConcurrent {
    def main(args: Array[String]): Unit = {

        val Factory = ActorSystem("Factory")
        //创建Actor对象工厂
        
        var t1 = Factory.actorOf(Props[Transfer], "t1")
        var t2 = Factory.actorOf(Props[Transfer], "t2")
		//通过对象工厂取得Actor类的实例,类型为ActorRef
		
        var from = Factory.actorOf(Props(new Account("from", 1000)), "from")
        var to = Factory.actorOf(Props(new Account("to", 1500)), "to")
		//还可以创建带参数的ActorRef
		
        for (i <- 1 until 10) {
            println(s"$i")
            t1 ! TransferMessage(1, from, to, 200)
            t2 ! TransferMessage(2, from, to, 400)
        }
        //重复十次取款存款
    }
}

case class TransferMessage(id: Int, from: ActorRef, to: ActorRef, amt: Int)
case class WithDrawMessage(oid: Int, amt: Int, mto: ActorRef)
case class DepositeMessage(oid: Int, amt: Int)
//case clas,代表转账,扣款和存款三种操作,其成员包含ActorRef类

//转账类
class Transfer extends Actor {

    override def receive: Receive = {
        case TransferMessage(id, from, to, amt) => {
            println(s"transfer $amt from $from to $to");
            from ! WithDrawMessage(id, amt, to)
        }
        //如果收到转账消息,首先向to对象发送扣款消息

        case "not_sufficient_money" =>
            println("you totally broke")
        //如果被扣款账号返回余额不足,显示 你是个穷鬼!

        case _ => println("unknown message")
    }

}


class Account(var name: String, var balance: Int) extends Actor {

    override def receive: Receive = {
        case WithDrawMessage(oid, amt, mto) => {
            if (withdraw(amt)) {
                mto ! DepositeMessage(oid, amt)
                println(s"sending message to $mto")
            } else
                sender ! "not_sufficient_money"
        }
		//收到来自transfer的扣款消息,如果余额充足,扣款,发送给存款账户存款消息;否则向sender发送余额不足

        case DepositeMessage(oid, amt) => {
            deposit(amt)
            println("you are rich")
        }
        //收到存款消息,存款,显示 有钱人

        case _ => println("unknown message")
    }

    def deposit(amt: Int): Unit = {
        balance += amt
        System.out.println("RMB" + amt + " has been deposited into " + name)
    }
	//取款方法
	
    def withdraw(amt: Int): Boolean = {
        if (balance > amt) {
            balance -= amt;
            System.out.println("RMB" + amt + " has been withdrawed from " + name)
            return true
        } else {
            System.out.println("not enough money, your loser")
            return false
        }
    }
    //存款方法
}

结果
1
2
3
4
5
6
7
8
9
transfer 200 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 400 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 400 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 200 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
RMB200 has been withdrawed from from
transfer 200 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 400 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 200 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 400 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 200 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 400 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 200 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 400 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 200 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 400 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 200 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 400 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
transfer 200 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
RMB200 has been deposited into to
you are rich
sending message to Actor[akka://Factory/user/to#-155185484]
RMB400 has been withdrawed from from
transfer 400 from Actor[akka://Factory/user/from#-98407958] to Actor[akka://Factory/user/to#-155185484]
RMB400 has been deposited into to
you are rich
sending message to Actor[akka://Factory/user/to#-155185484]
not enough money, your loser
RMB200 has been withdrawed from from
you totally broke
RMB200 has been deposited into to
you are rich
sending message to Actor[akka://Factory/user/to#-155185484]
not enough money, your loser
not enough money, your loser
you totally broke
you totally broke
not enough money, your loser
not enough money, your loser
you totally broke
you totally broke
not enough money, your loser
not enough money, your loser
you totally broke
not enough money, your loser
not enough money, your loser
you totally broke
you totally broke
not enough money, your loser
not enough money, your loser
you totally broke
you totally broke
you totally broke
not enough money, your loser
you totally broke
not enough money, your loser
not enough money, your loser
not enough money, your loser
you totally broke
you totally broke
you totally broke

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值