Java共有変数の可視性研究(一)
1921 ワード
1.メインスレッドで別のスレッドthread 1を起動する
通常の状況では、flagはベースタイプ変数としてメインスレッドとスレッド1によってワークメモリにコピーされるため、メインスレッドがflagをtrueに変更した後、必ずメインメモリに書き込まれるとは保証されないため、スレッド1は常に実行されることが多い.ただし、メインスレッドがflagをtrueに設定してスレッド1を再起動すると、スレッド1は直ちに実行終了する.理由は次のとおりです.JavaメモリモデルはHappens-Beforeルールに従います.スレッド起動の原則があります.すなわち、startメソッドを呼び出すと、startメソッドの前のすべての操作の結果がメインメモリに同期され、新しいスレッドが作成された後、メインメモリからデータを取得する必要があります.これにより、startメソッド呼び出し前のすべての操作結果が、新しく作成されたスレッドに対して表示されます.したがって、スレッド1が起動すると、読み込まれたflag変数はtrueとなる.このhappens-beforeの原則を検討する前に、マスタースレッドから起動したスレッド1がマスタースレッドのflagコピーの値をコピーしたかどうかを考慮したことがあります.すなわち、サブスレッドとは親スレッドの一部のリソースを継承していますが、最後に親子スレッド継承とは関係ないことがわかりました.ただし、ThreadLocalから継承されたInheritableThreadLocalというクラスは、サブスレッド初期化時に親スレッドのInheritableThreadLocalタイプ変数をコピーする目的を達成し、継承を実現できることも知られている.拡張リンク:1、https://www.cnblogs.com/cookiezhi/p/5774583.html
public static void main(String[] args) {
Runnable demo = new MyRunnable(bonkBean);
Thread thread = new Thread(demo,"thread1");
/*try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}*/
flag = true;
thread1.start();
/*try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
e.printStackTrace();
}*/
}
private static class MyRunnable implements Runnable {
@Override
public void run() {
//System.out.println(Thread.currentThread().getName() + ":" + flag);
//synchronized (AbstractThriftCodecManagerTest.class){}
while (true) {
//synchronized (AbstractThriftCodecManagerTest.class){}
if (flag) {
break;
}
}
System.out.println(" ");
// System.out.println(Thread.currentThread().getName()+":"+ a);
}
}
通常の状況では、flagはベースタイプ変数としてメインスレッドとスレッド1によってワークメモリにコピーされるため、メインスレッドがflagをtrueに変更した後、必ずメインメモリに書き込まれるとは保証されないため、スレッド1は常に実行されることが多い.ただし、メインスレッドがflagをtrueに設定してスレッド1を再起動すると、スレッド1は直ちに実行終了する.理由は次のとおりです.JavaメモリモデルはHappens-Beforeルールに従います.スレッド起動の原則があります.すなわち、startメソッドを呼び出すと、startメソッドの前のすべての操作の結果がメインメモリに同期され、新しいスレッドが作成された後、メインメモリからデータを取得する必要があります.これにより、startメソッド呼び出し前のすべての操作結果が、新しく作成されたスレッドに対して表示されます.したがって、スレッド1が起動すると、読み込まれたflag変数はtrueとなる.このhappens-beforeの原則を検討する前に、マスタースレッドから起動したスレッド1がマスタースレッドのflagコピーの値をコピーしたかどうかを考慮したことがあります.すなわち、サブスレッドとは親スレッドの一部のリソースを継承していますが、最後に親子スレッド継承とは関係ないことがわかりました.ただし、ThreadLocalから継承されたInheritableThreadLocalというクラスは、サブスレッド初期化時に親スレッドのInheritableThreadLocalタイプ変数をコピーする目的を達成し、継承を実現できることも知られている.拡張リンク:1、https://www.cnblogs.com/cookiezhi/p/5774583.html