加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读