我拿一个List[Int]
并想要搜索一个值x
where x * 10 > 500
在平行下。所以exists
应该返回true
如果列表包含 51 或更大的任何值。
def f(x: Int) = {
println("calculating for " + x)
Thread.sleep(100 - x)
println("finished " + x)
x * 10
}
val res = List.range(1, 100).par.exists(f(_) > 500)
结果如下:
calculating for 1
calculating for 25
calculating for 50
calculating for 75
calculating for 13
finished 75 // <-- first valid result found: 75 * 10 > 500
finished 50
calculating for 51 // but it kicks off more expensive calculations
finished 25
calculating for 26
finished 13
calculating for 14
finished 1
calculating for 2
finished 51
finished 26
calculating for 27 // and more
finished 14
calculating for 15
finished 2
calculating for 3
finished 27
calculating for 28
finished 15
calculating for 16
finished 3
calculating for 4 // and more...
finished 28
calculating for 29
finished 16
calculating for 17
finished 29
calculating for 30
finished 4
calculating for 5
finished 17
calculating for 18
finished 30
finished 5
calculating for 6
finished 18
finished 6
res: Boolean = true
我使用的是 Scala 2.9.1 的双核机器。
这里发生了什么?这是否按预期工作?为什么它不在找到第一个结果后立即向其他线程发送消息以中止任务?这可能会非常昂贵,如果f
是一个昂贵的计算。
find
似乎以类似的方式工作,搜索更多的值,即使文档说“元素可能不一定是迭代顺序中的第一个这样的元素”并且“选择是不确定的”。
为什么它不直接向其他线程发送消息以中止
一旦找到第一个结果就立即执行任务?
因为那是不可能的。 JAVA 不允许你这样做。或者更确切地说,它确实如此,但已被弃用。
请参阅(已弃用)的说明Thread.stop()
:
这种方法本质上是不安全的。使用 Thread.stop 停止线程
使其解锁所有已锁定的监视器(作为
未经检查的 ThreadDeath 异常传播的自然结果
堆栈上)。如果之前受这些保护的任何对象
监视器处于不一致状态,损坏的对象变成
对其他线程可见,可能导致任意行为。
stop 的许多用法应该被替换为简单修改某些内容的代码
变量来指示目标线程应该停止运行。这
目标线程应该定期检查这个变量,并从
如果变量指示它以有序的方式运行它的方法
就是停止运行。如果目标线程等待很长时间(在
例如条件变量),应使用中断方法
中断等待。有关更多信息,请参阅为什么Thread.stop,
Thread.suspend 和 Thread.resume 已弃用?.
换句话说,因为带锁的多线程代码本质上是被破坏的,所以他们不赞成一种完美的方法,这种方法可以愉快地与不共享可变状态的线程一起使用,因此不需要锁定数据结构。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)