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

将Scala @suspendable方法转换为未来

发布时间:2020-12-16 09:10:31 所属栏目:安全 来源:网络整理
导读:假设我有一个睡眠功能: def sleep(delay:Int) : Unit @suspendable = { ....} 是否可能有一个功能未来,创建可以等待同步的休眠功能的异步版本. def future(targetFunc: (Int = Unit @suspendable)) : (Int = Future) = { ....}class Future { def await : U
假设我有一个睡眠功能:

def sleep(delay:Int) : Unit @suspendable = {
  ....
}

是否可能有一个功能未来,创建可以等待同步的休眠功能的异步版本.

def future(targetFunc: (Int => Unit @suspendable)) : (Int => Future) = {
    ....
}

class Future {
  def await : Unit @suspendable = {
     ....
  }
}

你应该能够这样做:

reset {
  val sleepAsync = future(sleep)
  val future1 = sleepAsync(2000)
  val future2 = sleepAsync(3000)
  future1.await
  future2.await
  /* finishes after a delay of 3000 */
}

sleepAsync的两个调用应该会立即返回,而对于Future#await的两个调用应该会阻塞.当然,它们都真的从复位结束掉落,代码之后负责在延迟后调用延续.

否则有一种替代方法来并行运行两个@suspendable函数,并等待它们完成?

我有一个可编辑的要点,我想做一个骨架:https://gist.github.com/1191381

解决方法

object Forks {

  import scala.util.continuations._

  case class Forker(forks: Vector[() => Unit @suspendable]) {
    def ~(block: => Unit @suspendable): Forker = Forker(forks :+ (() => block))
    def joinIf(pred: Int => Boolean): Unit @suspendable = shift { k: (Unit => Unit) =>
      val counter = new java.util.concurrent.atomic.AtomicInteger(forks.size)
      forks foreach { f =>
        reset {
          f()
          if (pred(counter.decrementAndGet)) k()
        }
      }
    }
    def joinAll() = joinIf(_ == 0)
    def joinAny() = joinIf(_ == forks.size - 1)
  }

  def fork(block: => Unit @suspendable): Forker = Forker(Vector(() => block))
}

使用fork(),我们现在可以等待很多“suspendables”.使用?()链接在一起挂起.使用joinAll()等待所有suspendables和joinAny()等待一个.使用joinIf()自定义加入策略.

object Tests extends App {

  import java.util.{Timer,TimerTask}
  import scala.util.continuations._

  implicit val timer = new Timer

  def sleep(ms: Int)(implicit timer: Timer): Unit @suspendable = {
    shift { k: (Unit => Unit) =>
      timer.schedule(new TimerTask {
        def run = k()
      },ms)
    }
  }

  import Forks._

  reset {
    fork {
      println("sleeping for 2000 ms")
      sleep(2000)
      println("slept for 2000 ms")
    } ~ {
      println("sleeping for 4000 ms")
      sleep(4000)
      println("slept for 4000 ms")
    } joinAll()
    println("and we are done")
  }
  println("outside reset")
  readLine
  timer.cancel
}

这是输出.节目开始于时间T:

sleeping for 2000 ms
sleeping for 4000 ms
outside reset         <<<<<< T + 0 second
slept for 2000 ms     <<<<<< T + 2 seconds
slept for 4000 ms     <<<<<< T + 4 seconds
and we are done       <<<<<< T + 4 seconds

(编辑:李大同)

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

    推荐文章
      热点阅读