我想用
scalaz.concurrent.Task实现异步处理。我需要一个函数(Task[A], Task[B]) => Task[(A, B)]
来返回一个如下工作的新任务:
Task[A]
和Task[B]
并等待结果; 你将如何实现这样的功能?
答案 0 :(得分:3)
如上所述,如果您不关心实际停止未失败的计算,可以使用Nondeterminism
。例如:
import scalaz._, scalaz.Scalaz._, scalaz.concurrent._
def pairFailSlow[A, B](a: Task[A], b: Task[B]): Task[(A, B)] = a.tuple(b)
def pairFailFast[A, B](a: Task[A], b: Task[B]): Task[(A, B)] =
Nondeterminism[Task].both(a, b)
val divByZero: Task[Int] = Task(1 / 0)
val waitALongTime: Task[String] = Task {
Thread.sleep(10000)
println("foo")
"foo"
}
然后:
pairFailSlow(divByZero, waitALongTime).run // fails immediately
pairFailSlow(waitALongTime, divByZero).run // hangs while sleeping
pairFailFast(divByZero, waitALongTime).run // fails immediately
pairFailFast(waitALongTime, divByZero).run // fails immediately
除了第一种情况外,waitALongTime
中的副作用都会发生。如果您想尝试停止该计算,则需要使用Task
' s runAsyncInterruptibly
之类的内容。
答案 1 :(得分:2)
java开发人员之间有一个奇怪的概念,你不应该取消并行任务。他们对Thread.stop()
进行了授权并将其标记为已弃用。没有Thread.stop()
你就无法取消未来。您所能做的就是向未来发送一些信号,或者修改一些共享变量并在将来制作代码以定期检查它。因此,所有提供期货的图书馆都可以建议取消未来的唯一方法:合作做。
我现在面临同样的问题,正在编写我自己的图书馆,可以取消期货。有一些困难,但可以解决。你无法在任意位置调用Thread.stop()。线程可以执行更新共享变量。锁定将被正常调用,但更新可能会在中途停止,例如只更新double值的一半,依此类推。所以我引入了一些锁定。如果线程处于保护状态,那么它现在应该被Thread.stop()杀死,但是发送特定的消息。守卫状态被认为总是很快等待。所有其他时间,在计算过程中,线程可以安全地停止并替换为新线程。
所以,答案是:你不应该想取消期货,否则你就是异教徒,java社区中没有人愿意帮你。你应该定义你自己的执行上下文,它可以杀死线程,你应该编写自己的期货库来运行这个上下文