让我们想象下一段 Kotlin 代码通过 JDBC 连接器对数据库执行一些查询:
var results : ResultSet
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
results = preparedStatement.executeQuery()
while(results.next()) {
// parse results
}
编译没有问题。但是,当我尝试将线程安全添加到对preparedStatement 的访问时:
var results : ResultSet
synchronized(preparedStatement) {
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
results = preparedStatement.executeQuery()
}
while(results.next()) {
// parse results
}
...我得到一个“必须初始化变量'结果'”。似乎 synchronized
block 充当条件 block ,但您可以确定它会在 while
block 之前执行一次。
我已经在 Java 中实现了这个相同的 block ,但我没有收到错误。这是 Kotlin 的设计/实现错误吗?还是有充分的理由这样做?
最佳答案
synchronized
只是一个内联函数,编译器不知道 lambda 是否会执行一次,甚至根本不会执行。惯用的方法是从 lambda 返回值并将其分配给本地:
val results =
synchronized(preparedStatement) {
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
preparedStatement.executeQuery()
}
关于thread-safety - Kotlin: "synchronized"使编译器不确定变量的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36246511/