2011-11-10 2 views
3

이들 두 원자 동작이다 :원자는 무엇입니까?

int value = 5; 
Object obj = new Object(); 

하지만 방법 매개 변수로 프리미티브를 사용하는 경우, 이는 원자 조작으로 간주 될 것이다 : public void setValue(int val, Object obj){
this.value = val; // Atomic?
this.obj = obj; // Not atomic?
}

? 개체 참조의 복사본은 읽기 및 쓰기가 포함되어 있기 때문에 어둡지 않습니다.

Object obj = null; 

Object obj = new Object(); 
:

하는 것이 유일한 방법은 객체 참조에 원자 작업을하기 위해 말을 정확 것인가하는 것은 null를 선언하거나 같은 해 새로운 객체를 할당하는 것입니다

?

답변

4

위의 메서드의 매개 변수가 개체에 대한 참조 인 경우 작업은 원자 적이지 않은 것입니까?

일반적으로 이는 정확합니다. 엄지 손가락의 좋은 규칙도 같은 프리미티브, 더 자성이 전혀 없다 고려하는 것입니다 :

int b,c; 
int a = ++b - c; 

만 프리미티브하지만, 전체 할당은 원자 가능성이 없습니다. 당신은 원자 작업을 enshure 필요한 경우

당신은 개의 다른 posibilities 있습니다

  • 동기화 블록을
  • 불변의 객체
  • 특정 라이브러리 (java.util.concurrent.atomic의)
+0

답변 해 주셔서 감사합니다. 또한 질문을 편집하여 메서드 호출에서 객체 참조를 사용할 때 코드 예제가 포함되었습니다. – Rox

0
public synchronized void setValue(int val, Object obj) 

이제 전체 함수는 "원자"입니다.이 용어는 Java에서 사용 된 적이 없습니다.

스레드 변수 값을 사용하는 경우
1

To the JLS!

, 그것은 획득 값은 실제로 스레드 또는 다른 스레드에 의해 변수에 저장된 값이다. 프로그램에 적절한 동기화 코드가 포함되지 않은 경우에도 마찬가지입니다. 예를 들어, 두 개의 스레드가 다른 객체에 대한 참조를 동일한 참조 값에 저장하면 변수는 다른 객체에 대한 참조 나 손상된 참조 값이 아닌 한 객체 또는 다른 객체에 대한 참조를 포함하게됩니다.

따라서 할당은 원자 적입니다.

3

스레드가 프리미티브 (long 및 double 제외) 또는 객체 참조 값을 읽으면이 변수에 설정된 값이나 다른 스레드가이 변수에 설정 한 값을 봅니다.

그러나 하나의 스레드에서 공유 변수에 값을 할당하는 것은 원 자성 임에도 불구하고 다른 모든 스레드가 새 값을 바로 볼 수 있음을 의미하지는 않습니다.그렇게하기 위해 변수는 volatile로 선언되어야합니다. 휘발성은 또한 long 및 double 원자에 쓰기를 만듭니다. AtomicXxx (AtomicLong, AtomicBoolean 등)를 사용하는 것을 선호합니다.

두 개의 공유 변수 값을 원자 적으로 변경하려면 고유 한 잠금을 사용하여 이러한 변수에 대한 모든 액세스 (읽기 및 쓰기)를 동기화해야합니다.

또한 "점검 후 작동"또는 "읽기 후 쓰기"조작은 비 원자력입니다. 즉, 이러한 작업에도 동기화가 필요합니다.

a++; // read a, increment value, write value to a 
if (a > 0) {a = b;} // check value of a, then assign new value to a. 

질문에있는 모든 단일 작업은 원자 적입니다. 그러나 setValue()에는 두 개의 원자 연산이 있습니다. 전체 setValue 콜은 원자 적이지 않습니다.

+0

"Happen Before"관계에 대해 언급 해 주셔서 감사합니다. – dmeister