同期メソッドがロックされている場合、非同期メソッドは同期メソッドで変更された変数にアクセスできますか?
次のシナリオを考慮します.
1つのclassにメンバー変数bがあります.
メンバメソッドm 1()は同期メソッドであり、bを操作する.
メンバーメソッドm 2()は同期メソッドではなく、bにアクセスする.
では、m 1()がbをロックした場合、m 2()は実行できますか?
もしできるなら、得られたbは修正前ですか、それとも修正後ですか.
m 2()も同期方法だったら?
控訴問題を以下のようにコード化し、m 2()が同期方法でない場合:
この場合、testで初期化されたスレッドtはrunメソッド(m 1)を先に実行し、その後、メインスレッドは1秒睡眠し(bがロックされて1000に変更されたことを保証し)、その後testのm 2()メソッドを呼び出して実行する.
発生する可能性のある状況は次のとおりです.
1、誤報
2,先にb=1000を印刷して、更に1000を印刷します.
説明m 1()実行時m 2()は実行できません(m 2()などm 1()睡眠5秒が終了してから実行します)
3,先に100を印刷して、更にb=1000を印刷します
m 1がbをロックする5秒以内に、m 2()は依然としてbにアクセスでき、b修正前の値が得られることを説明する.
4まず100を印刷し、b=1000を印刷する
m 1がbをロックする5秒以内に、m 2()は依然としてbにアクセスでき、b修正後の値が得られることを説明する.
実際、得られた結果は以下の通りです.
synchronized修飾メソッドで実行される場合、通常のメソッドでもsynchronizedメソッドの変数にアクセスできることを示します.
ではm 2()もsynchronizedに修飾されたら?
結果は次のとおりです.
m 1()の実行が完了してから、m 2()が実行できる.
1つのclassにメンバー変数bがあります.
メンバメソッドm 1()は同期メソッドであり、bを操作する.
メンバーメソッドm 2()は同期メソッドではなく、bにアクセスする.
では、m 1()がbをロックした場合、m 2()は実行できますか?
もしできるなら、得られたbは修正前ですか、それとも修正後ですか.
m 2()も同期方法だったら?
控訴問題を以下のようにコード化し、m 2()が同期方法でない場合:
package thread;
public class Test implements Runnable{
private int b =100;
public synchronized void m1(){
b=1000;
try{
Thread.sleep(5000);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("b="+b);
}
public void m2()
{
System.out.println(b);
}
public void run(){
m1();
}
public static void main(String[] args){
Test test=new Test();
Thread t=new Thread(test);
t.start();
try{
Thread.sleep(1000);
}catch(Exception e){
}
test.m2();
}
}
この場合、testで初期化されたスレッドtはrunメソッド(m 1)を先に実行し、その後、メインスレッドは1秒睡眠し(bがロックされて1000に変更されたことを保証し)、その後testのm 2()メソッドを呼び出して実行する.
発生する可能性のある状況は次のとおりです.
1、誤報
2,先にb=1000を印刷して、更に1000を印刷します.
説明m 1()実行時m 2()は実行できません(m 2()などm 1()睡眠5秒が終了してから実行します)
3,先に100を印刷して、更にb=1000を印刷します
m 1がbをロックする5秒以内に、m 2()は依然としてbにアクセスでき、b修正前の値が得られることを説明する.
4まず100を印刷し、b=1000を印刷する
m 1がbをロックする5秒以内に、m 2()は依然としてbにアクセスでき、b修正後の値が得られることを説明する.
実際、得られた結果は以下の通りです.
1000
b=1000
synchronized修飾メソッドで実行される場合、通常のメソッドでもsynchronizedメソッドの変数にアクセスできることを示します.
ではm 2()もsynchronizedに修飾されたら?
package thread;
public class Test implements Runnable{
private int b =100;
public synchronized void m1(){
b=1000;
try{
Thread.sleep(5000);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("b="+b);
}
public synchronized void m2()
{
System.out.println(b);
}
public void run(){
m1();
}
public static void main(String[] args){
Test test=new Test();
Thread t=new Thread(test);
t.start();
try{
Thread.sleep(1000);
}catch(Exception e){
}
test.m2();
}
}
結果は次のとおりです.
b=1000
1000
m 1()の実行が完了してから、m 2()が実行できる.