幕布斯6054654
2019-01-17 15:45:03
1、想了解不同類型線程之間的關系(此程序沒考慮線程安全問題),想模擬電腦是怎樣執(zhí)行多線程,但是得到一個莫名奇妙的結果。思考了很長時間,還是沒有解決,希望能得到幫助;
2、代碼如下
public class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
SetThread st = new SetThread(s);
GetThread gt = new GetThread(s);
Thread t1 = new Thread(st, "SetTread");
Thread t2 = new Thread(gt,"GetTread");
t2.start();
t1.start();
}
}
public class Student {
public String name;
public int age;
}
public class SetThread implements Runnable{
private Student s;
public SetThread(Student s) {
this.s = s;
}
@Override
public void run() {
s.name = "jzian";
s.age = 27;
}
}
public class GetThread implements Runnable {
private Student s;
public GetThread(Student s) {
this.s = s;
}
@Override
public void run() {
System.out.println( s.name + "-----" + s.age);
}
}
3、得到的結果為:null----27請問是怎樣得到這樣的結果的?
4 回答

揚帆大魚
TA貢獻1799條經(jīng)驗 獲得超9個贊
這個應該與指令重排序沒有關系。編譯器在某些情況下會對指令的順序進行重排,但是肯定是基于一定的理由。這段代碼我看不出來為什么要重排指令順序。
我認為原因很可能出在可見性上。兩個變量都不是volatile的,因此無法保證在一個線程中賦值后在另一個線程中一定可見??梢試L試加上volatile,然后看看還會不會出現(xiàn)這種情況。如果不會出現(xiàn),那么就與指令重排無關

慕運維8079593
TA貢獻1876條經(jīng)驗 獲得超5個贊
java多線程調度方式默認是搶占式。線程t1執(zhí)行到一半(給age賦完值),這時候t2搶到了執(zhí)行權,打印出來就只有age,name為String類型的默認值。

FFIVE
TA貢獻1797條經(jīng)驗 獲得超6個贊
問題出在這里
t2.start();
t1.start();
線程先執(zhí)行get方法,set方法你還沒設值,所以默認是null和0,為什么有時候有值呢,由于線程隨機性,有時候t1先執(zhí)行,t2后執(zhí)行,就得到27,zjan
先這樣改
t1.start();
t2.start();
如果要保證得到的都是27,zjan還要保證線程同步性,上面說的加關鍵字volatie以及synchronize都能解決
手機碼字,見諒
添加回答
舉報
0/150
提交
取消