자바 원시 정수 (int)는 전혀 중요하지 않습니까? int를 공유하는 두 개의 스레드를 사용하는 일부 실험은 이이라는 것을 나타내지 만 물론 이 아닌이라는 증거가 없다는 것을 의미하지는 않습니다.자바 원시적 인 int는 의도적으로 또는 우연히 원자입니까?
특히, 내가 실행 된 검사이 있었다 :
public class IntSafeChecker {
static int thing;
static boolean keepWatching = true;
// Watcher just looks for monotonically increasing values
static class Watcher extends Thread {
public void run() {
boolean hasBefore = false;
int thingBefore = 0;
while(keepWatching) {
// observe the shared int
int thingNow = thing;
// fake the 1st value to keep test happy
if(hasBefore == false) {
thingBefore = thingNow;
hasBefore = true;
}
// check for decreases (due to partially written values)
if(thingNow < thingBefore) {
System.err.println("MAJOR TROUBLE!");
}
thingBefore = thingNow;
}
}
}
// Modifier just counts the shared int up to 1 billion
static class Modifier extends Thread {
public void run() {
int what = 0;
for(int i = 0; i < 1000000000; ++i) {
what += 1;
thing = what;
}
// kill the watcher when done
keepWatching = false;
}
}
public static void main(String[] args) {
Modifier m = new Modifier();
Watcher w = new Watcher();
m.start();
w.start();
}
}
를 (그리고 단지 32 비트 윈도우 PC에 자바 JRE 1.6.0_07으로 시도되었다)
본질적으로, 수정은 카운트 순서를 기록 관찰자는 관측 된 값이 결코 감소하지 않는지를 확인하면서 공유 된 정수에 더한다. 32 비트 값을 4 개의 개별 바이트 (또는 심지어 2 개의 16 비트 워드)로 액세스해야하는 시스템에서는 Watcher가 일관성이없는 반 갱신 상태에서 공유 정수를 잡을 확률이 줄어들어 값이 감소합니다 증가하기보다는 오히려. 이는 (가설적인) 데이터 바이트가 LSB 1 또는 MSB 1로 수집되거나 기록되는지 여부에 따라 작동해야하지만 최상의 경우에만 probablistic입니다.
Java 사양에서 필요하지 않더라도 32 비트 값이 효과적으로 원 자성을 가질 수 있다는 오늘날의 광범위한 데이터 경로를 고려할 때 매우 가능성이 높습니다. 사실, 32 비트 데이터 버스를 사용하면 원자 접근을 얻기 위해 32 비트 정수보다 바이트까지 열심히 노력해야 할 수도 있습니다.
"java primitive thread safety"를 검색하면 스레드 안전 클래스 및 객체에 많은 양이 표시되지만 기본 요소에 대한 정보를 찾는 것은 건초 더미에서 속담 바늘을 찾는 것처럼 보입니다.
AtomicInteger 클래스가 있는지 궁금합니다. (http://java.sun.com/javase/6/docs/api/java/util/concurrent/atomic /AtomicInteger.html), 다음. – Joey
@Johannes Rössel - AtomicInteger에는 손상 가능성이없는 것보다 많은 정보가 있습니다. 가시성, CAS 기반 작업. –
그래, 나는 어떤면에서 AtomicInteger가 VolatileInteger로 명명되어야한다고 주장한다. –