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

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
请问是怎样得到这样的结果的?

幕布斯6054654
浏览 526回答 4
4回答

扬帆大鱼

这个应该与指令重排序没有关系。编译器在某些情况下会对指令的顺序进行重排,但是肯定是基于一定的理由。这段代码我看不出来为什么要重排指令顺序。 我认为原因很可能出在可见性上。两个变量都不是volatile的,因此无法保证在一个线程中赋值后在另一个线程中一定可见。可以尝试加上volatile,然后看看还会不会出现这种情况。如果不会出现,那么就与指令重排无关

至尊宝的传说

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

慕运维8079593

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

FFIVE

问题出在这里t2.start(); t1.start(); 线程先执行get方法,set方法你还没设值,所以默认是null和0,为什么有时候有值呢,由于线程随机性,有时候t1先执行,t2后执行,就得到27,zjan先这样改t1.start(); t2.start();如果要保证得到的都是27,zjan还要保证线程同步性,上面说的加关键字volatie以及synchronize都能解决手机码字,见谅
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java