在Scala演员中访问共享资源的正确方法
发布时间:2020-12-16 19:07:04 所属栏目:安全 来源:网络整理
导读:在 Java中,可以同步访问多线程环境中所需的共享资源的方法或块. 我想知道“Scala演员”的做法如何运作. 假设我有一个java.sql.Connection对象的连接池,我希望提供线程安全的访问.我实现它作为一个接收消息并向发送方发送连接的演员. 看来有三种方法可以做到
在
Java中,可以同步访问多线程环境中所需的共享资源的方法或块.
我想知道“Scala演员”的做法如何运作. 假设我有一个java.sql.Connection对象的连接池,我希望提供线程安全的访问.我实现它作为一个接收消息并向发送方发送连接的演员. 看来有三种方法可以做到这一点: >使用未来 码: sealed abstract class ConnectionPoolMessage case class NewConnection extends ConnectionPoolMessage case class CloseConnection(c:Connection) extends ConnectionPoolMessage class ConnectionPool extends Actor { def act() { while (true) { receive() { case NewConnection => sender ! getConnectionFromPool case CloseConnection(conn) => returnConnection(conn) } } } } // Here,my "do stuff" method is all in one place,and I block waiting // on the Future from the pool; however this could take forever and cause trouble class UsingFuture { val pool = new ConnectionPool def doSomething() { val connectionFuture = pool !! NewConnection val connection = connectionFuture() // concerned that we can't timeout here // do stuff with my Connection instance pool ! CloseConnection(connection) } } // here,I wait and just use a timeout // Seems clean to me,I guess. class UsingBangQuestion { val pool = new ConnectionPool def doSomething() { pool !?(TIMEOUT,NewConnection) match { case Some(conn) => { // do something with connection pool ! CloseConnection(conn) } case None => throw new RuntimeException("timed out") } } } // here,I don't worry about timeouts,cause I only use the // the connection when I receive a message back with it. // The problem is that I now have to split my logic up // with two methods class AsAnActor extends Actor { val pool = new ConnectionPool def startSomething() { start pool ! NewConnection } def act() { receive() { case conn:Connection => finishSomething(conn) } } def finishSomething(conn:Connection) { // do stuff with my Connection pool ! CloseConnection(conn) } } 未来版本似乎是最干净的,除了我可以阻止永远的事实. 有什么想法,还是我的这个错误的概念? 解决方法
它可能是不好的风格,但一种方法是通过让您的actor(需要连接)直接插入连接池并使用同步来获取连接来混合命令式和功能性样式.说实话,我真的不明白这种做法有什么问题;我更喜欢这个!!或者!一个,只是尖叫死锁(甚至活锁)!
我猜其他的方式是发送一个消息到你的池,表示需要完成的连接和结果的可能目标的工作: class DbWork(f: Connection => Unit) class DbWorkWithResult[T](f:Connection => T,target: OutputChannel[Any]) 然后你可以使用它: pool ! new DbWork( { (conn: Connection) => //do something }) 要么: pool ! new DbWorkWithResult[Int]( (conn: Connection) => //return int },self) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |