将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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |