为了账号安全,请及时绑定邮箱和手机立即绑定

使用java多线程时得到不可思议的结果,想了好长时间都模拟不出是怎样得到的?

使用java多线程时得到不可思议的结果,想了好长时间都模拟不出是怎样得到的?

幕布斯6054654 2019-01-17 15:45:03
1、想了解不同类型线程之间的关系(此程序没考虑线程安全问题),想模拟电脑是怎样执行多线程,但是得到一个莫名奇妙的结果。思考了很长时间,还是没有解决,希望能得到帮助; 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条经验 获得超9个赞

这个应该与指令重排序没有关系。编译器在某些情况下会对指令的顺序进行重排,但是肯定是基于一定的理由。这段代码我看不出来为什么要重排指令顺序。

我认为原因很可能出在可见性上。两个变量都不是volatile的,因此无法保证在一个线程中赋值后在另一个线程中一定可见。可以尝试加上volatile,然后看看还会不会出现这种情况。如果不会出现,那么就与指令重排无关

查看完整回答
反对 回复 2019-03-01
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

子线程s1和s2的执行顺序不确定,所以你说的结果是可能的结果中的一种

查看完整回答
反对 回复 2019-03-01
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

java多线程调度方式默认是抢占式。线程t1执行到一半(给age赋完值),这时候t2抢到了执行权,打印出来就只有age,name为String类型的默认值。

查看完整回答
反对 回复 2019-03-01
?
FFIVE

TA贡献1797条经验 获得超6个赞

问题出在这里
t2.start();
t1.start();

线程先执行get方法,set方法你还没设值,所以默认是null和0,为什么有时候有值呢,由于线程随机性,有时候t1先执行,t2后执行,就得到27,zjan
先这样改
t1.start();
t2.start();
如果要保证得到的都是27,zjan还要保证线程同步性,上面说的加关键字volatie以及synchronize都能解决
手机码字,见谅

查看完整回答
反对 回复 2019-03-01
  • 4 回答
  • 0 关注
  • 525 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信