Ленивые значения Scala:штраф за производительность?Потокобезопасность?[дубликат]
-
28-09-2019 - |
Вопрос
Возможный дубликат:
Какова (скрытая) стоимость lazy val?(Скала)
Scala позволяет определять ленивые значения
lazy val maybeUnusedValue = someCostlyInitialization
где someCostlyInitialization
оценивается только при первом использовании maybeUnusedValue
.То есть оно оценивается не более одного раза, и если maybeUnusedValue
никогда не используется, а также вообще никогда не оценивается.
Это потокобезопасно?Каковы последствия этого для производительности?Если это должно быть потокобезопасным, оно должно использовать какую-то синхронизацию/использовать каким-то образом изменчивую Java.К сожалению, Спецификация языка Scala ничего об этом не говорит.
Решение
Он сделан потокобезопасным с использованием блокировки с двойной проверкой. http://code-o-matic.blogspot.com/2009/05/double-checked-locking-idiom-sweet-in.html Очевидно, это означает, что доступ к ленивым значениям происходит медленнее, чем к неленивым.
Другие советы
ОБНОВЛЯТЬ:Упс, как заметил Василий, вопрос является копией другой темы, как и этот ответ.
Я взял этот класс:
class Foo {
lazy val test = "hi"
}
Скомпилировано и декомпилировано (с помощью jd-gui):
public class Foo
implements ScalaObject
{
private String test;
public volatile int bitmap$0;
public String test()
{
if (
(this.bitmap$0 & 0x1) == 0);
synchronized (this)
{
if (
(this.bitmap$0 & 0x1) == 0) {
this.test = "hi"; this.bitmap$0 |= 1; } return this.test;
}
}
}
Как вы можете видеть, здесь используется парадигма двойной проверки с изменчивой переменной.Так что я думаю, что это безопасно