好的问题可能不多说,但这是交易: 我正在学习scala,并决定使用一个方法来创建一个实用程序类“FuncThread”,该方法接收一个名称参数函数(我想它的名字是因为它是一个函数但没有参数列表)然后启动一个带有可运行的线程反过来执行传递的函数,我写了如下类:
class FuncThread
{
def runInThread( func: => Unit)
{
val thread = new Thread(new Runnable()
{
def run()
{
func
}
}
thread.start()
}
}
然后我写了一个如下的junit测试:
@Test
def weirdBehaivorTest()
{
var executed = false
val util = new FuncThread()
util.runInThread
{
executed = true
}
//the next line makes the test pass....
//val nonSense : () => Unit = () => { Console println "???" }
assertTrue(executed)
}
如果我取消注释第二个注释行,则测试通过,但如果它仍然被注释,则测试失败,这是正确的行为吗? by-name参数函数如何以及何时执行?
我知道Scala有actor库但我想尝试这个,因为我一直想用Java做这个
答案 0 :(得分:7)
这只是竞争条件吗? runInThread启动线程,但是在另一个线程将其设置为true之前,您的断言测试'已执行'。添加额外的行意味着在测试之前执行更多的代码(以及时间),使“执行”更有可能被设置为真
答案 1 :(得分:4)
值得注意的是(从Scala 2.8开始),您尝试编写的构造在标准库中可用
import scala.actors.Futures._
future{
executed = true
}
这个构造实际上比你描述的更强大,线程计算可以返回一个值,并且可以等待它。
import scala.actors.Futures._
//forks off expensive calculation
val expensiveToCalculateNumber:Future[Int] = future{
bigExpensiveCalculation()
}
// do a lot of other stuff
//print out the result of the expensive calculation if it's ready, otherwise wait until it is
println( expensiveToCalculateNumber());