Ленивые значения Scala:штраф за производительность?Потокобезопасность?[дубликат]

StackOverflow https://stackoverflow.com/questions/4095170

Вопрос

Возможный дубликат:
Какова (скрытая) стоимость 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;
    }
  }
}

Как вы можете видеть, здесь используется парадигма двойной проверки с изменчивой переменной.Так что я думаю, что это безопасно

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top