복붙노트

[SCALA] 동시성 가시성 발 대 스칼라 최종

SCALA

동시성 가시성 발 대 스칼라 최종

객체를 여러 스레드에서 (그리고 일반적으로) 사용할 때 자바에서, 필드를 최종 확인하는 것이 좋습니다. 예를 들어,

public class ShareMe {
    private final MyObject obj;
    public ShareMe(MyObject obj) {
        this.obj = obj;
    }
}

이 경우, OBJ의 가시성이 안전하게 최종 키워드를 사용하여 구성되어 있기 때문에 (하자가 OBJ뿐만 아니라 모든 최종 필드가 가정) 여러 스레드에서 일관성이 될 것입니다.

스칼라에서는 최종 참조 아래로 발 컴파일 표시되지 않는, 오히려 발 그 (생성자 스칼라 최종 변수) 변수를 재 할당에서 방지를 스칼라 의미입니다. 스칼라 생성자 변수가 마지막으로 정의되어 있지 않은 경우 (배우에서 이러한 개체를 사용하는 경우), 그들은 같은 문제로 고통 것인가?

해결법

  1. ==============================

    1.다른 질문에 대한 답변은 잘못된 것입니다. 최종 기간의 두 가지 의미가 있습니다 스칼라 필드 / 방법과 Java 메소드에 대한)이 그것 필드가 생성자에서 초기화해야합니다 "를 의미 바이트 코드 자바 필드와 JVM에서와 b)"하위 클래스에서 재정의 할 수 없습니다 "의미 그리고 "재 할당 할 수 없습니다.

    다른 질문에 대한 답변은 잘못된 것입니다. 최종 기간의 두 가지 의미가 있습니다 스칼라 필드 / 방법과 Java 메소드에 대한)이 그것 필드가 생성자에서 초기화해야합니다 "를 의미 바이트 코드 자바 필드와 JVM에서와 b)"하위 클래스에서 재정의 할 수 없습니다 "의미 그리고 "재 할당 할 수 없습니다.

    발 표시된 클래스 파라미터 (또는, 등가 적으로, 개질제가없는 경우 클래스 파라미터)가 실제로 제 2 감지의 최종 결과이며, 따라서 스레드 안전.

    여기 증거 :

    scala>  class A(val a: Any); class B(final val b: Any); class C(var c: Any)
    defined class A
    defined class B
    defined class C
    
    scala> import java.lang.reflect._
    import java.lang.reflect._
    
    scala> def isFinal(cls: Class[_], fieldName: String) = {
         |   val f = cls.getDeclaredFields.find(_.getName == fieldName).get
         |   val mods = f.getModifiers
         |   Modifier.isFinal(mods)
         | }
    isFinal: (cls: Class[_], fieldName: String)Boolean
    
    scala> isFinal(classOf[A], "a")
    res32: Boolean = true
    
    scala> isFinal(classOf[B], "b")
    res33: Boolean = true
    
    scala> isFinal(classOf[C], "c")
    res34: Boolean = false
    

    또는 편리하게 REPL에서 실행할 수 있습니다은 javap과 :

    scala> class A(val a: Any)
    defined class A
    
    scala> :javap -private A
    Compiled from "<console>"
    public class A extends java.lang.Object implements scala.ScalaObject{
        private final java.lang.Object a;
        public java.lang.Object a();
        public A(java.lang.Object);
    }
    
  2. ==============================

    2.나는 VAR이 컴파일 어떻게 오해가있을 수 있습니다 생각합니다. 나는 샘플 클래스를 생성

    나는 VAR이 컴파일 어떻게 오해가있을 수 있습니다 생각합니다. 나는 샘플 클래스를 생성

    class AVarTest(name:String) {
       def printName() {
         println(name)
       }
    }
    

    난은 javap - 개인 실행하며 결과

    public class AVarTest extends java.lang.Object implements scala.ScalaObject{
        private final java.lang.String name;
        public void printName();
        public AVarTest(java.lang.String);
    }
    

    그리고 이름은 실제로 마지막으로 컴파일됩니다.

    또한 스칼라 발에 표시됩니다 이것은 동시 액세스를 동기화로 보호되어야한다?

  3. from https://stackoverflow.com/questions/7626611/scala-final-vs-val-for-concurrency-visibility by cc-by-sa and MIT license