[SCALA] 동시성 가시성 발 대 스칼라 최종
SCALA동시성 가시성 발 대 스칼라 최종
객체를 여러 스레드에서 (그리고 일반적으로) 사용할 때 자바에서, 필드를 최종 확인하는 것이 좋습니다. 예를 들어,
public class ShareMe {
private final MyObject obj;
public ShareMe(MyObject obj) {
this.obj = obj;
}
}
이 경우, OBJ의 가시성이 안전하게 최종 키워드를 사용하여 구성되어 있기 때문에 (하자가 OBJ뿐만 아니라 모든 최종 필드가 가정) 여러 스레드에서 일관성이 될 것입니다.
스칼라에서는 최종 참조 아래로 발 컴파일 표시되지 않는, 오히려 발 그 (생성자 스칼라 최종 변수) 변수를 재 할당에서 방지를 스칼라 의미입니다. 스칼라 생성자 변수가 마지막으로 정의되어 있지 않은 경우 (배우에서 이러한 개체를 사용하는 경우), 그들은 같은 문제로 고통 것인가?
해결법
-
==============================
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.나는 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); }
그리고 이름은 실제로 마지막으로 컴파일됩니다.
또한 스칼라 발에 표시됩니다 이것은 동시 액세스를 동기화로 보호되어야한다?
from https://stackoverflow.com/questions/7626611/scala-final-vs-val-for-concurrency-visibility by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 왜 검증 모나드 아닌가요? (scalaz7) (0) | 2019.11.20 |
---|---|
[SCALA] Implicits와 스칼라 기능 리터럴 (0) | 2019.11.20 |
[SCALA] 방법 반복자와보기의 차이점은 무엇입니까? (0) | 2019.11.20 |
[SCALA] 스칼라 열거 값을 재정의 (0) | 2019.11.20 |
[SCALA] 목록의 하나에 Eithers의 목록을 설정하는 가장 좋은 방법은? (0) | 2019.11.20 |