私の理解では、ハードウェアがマルチプロセッサ システムでキャッシュ コヒーレンスをサポートしている場合、共有変数への書き込みは、他のプロセッサで実行されているスレッドに表示されます。これをテストするために、Java と pThreads で簡単なプログラムを作成してテストしました。
public class mainTest {
public static int i=1, j = 0;
public static void main(String[] args) {
/*
* Thread1: Sleeps for 30ms and then sets i to 1
*/
(new Thread(){
public void run(){
synchronized (this) {
try{
Thread.sleep(30);
System.out.println("Thread1: j=" + mainTest.j);
mainTest.i=0;
}catch(Exception e){
throw new RuntimeException("Thread1 Error");
}
}
}
}).start();
/*
* Thread2: Loops until i=1 and then exits.
*/
(new Thread(){
public void run(){
synchronized (this) {
while(mainTest.i==1){
//System.out.println("Thread2: i = " + i); Comment1
mainTest.j++;
}
System.out.println("\nThread2: i!=1, j=" + j);
}
}
}).start();
/*
* Sleep the main thread for 30 seconds, instead of using join.
*/
Thread.sleep(30000);
}
}
/* pThreads */
#include<stdio.h>
#include<pthread.h>
#include<assert.h>
#include<time.h>
int i = 1, j = 0;
void * threadFunc1(void * args) {
sleep(1);
printf("Thread1: j = %d\n",j);
i = 0;
}
void * threadFunc2(void * args) {
while(i == 1) {
//printf("Thread2: i = %d\n", i);
j++;
}
}
int main() {
pthread_t t1, t2;
int res;
printf("Main: creating threads\n");
res = pthread_create(&t1, NULL, threadFunc1, "Thread1"); assert(res==0);
res = pthread_create(&t2, NULL, threadFunc2, "Thread2"); assert(res==0);
res = pthread_join(t1,NULL); assert(res==0);
res = pthread_join(t2,NULL); assert(res==0);
printf("i = %d\n", i);
printf("Main: End\n");
return 0;
}
pThread プログラムが常に終了することに気付きました。(スレッド1のさまざまなスリープ時間でテストしました)。ただし、Java プログラムが終了するのはごくわずかです。終わらないことがほとんどです。Java プログラムで Comment1 のコメントを外すと、常に終了します。また、揮発性を使用すると、すべての場合でJavaで終了します。
だから私の混乱は、
キャッシュの一貫性がハードウェアで行われる場合、コンパイラがコードを最適化しない限り、「i=0」は他のスレッドから見えるはずです。しかし、コンパイラがコードを最適化した場合、スレッドが終了する場合と終了しない場合がある理由がわかりません。また、 System.out.println を追加すると、動作が変わるようです。
この動作の原因となっている、Java が行うコンパイラの最適化 (C コンパイラでは行われない) を誰でも見ることができますか?
ハードウェアが既にサポートしている場合でも、キャッシュの一貫性を確保するために、コンパイラが行う必要がある追加のことはありますか? (有効化/無効化など)
デフォルトですべての共有変数に Volatile を使用する必要がありますか?
何か不足していますか?追加のコメントは大歓迎です。