多线程操作带来数据不一致情况分析,简单demo。
public class Object_IS {
    private Student_Object so = new Student_Object("张三", 123);
    public static void main(String[] args) throws InterruptedException {
        Object_IS os = new Object_IS();
        os.test1();
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(() -> {
                os.so = new Student_Object("李四", 900);
            });
            thread.start();
//            os.test1();
            os.test2();
            System.out.println("-------------------------------");
        }
    }
    public void test2() throws InterruptedException {
        String name = this.so.getName();
        //为了使问题暴漏,故意睡眠
        Thread.sleep(100);
        Integer code = this.so.getCode();
        System.out.println("name:" + name + "  code: " + code);
    }
    public void test1() {
        //相当于保持快照
        Student_Object so = this.so;
        String name = so.getName();
        Integer code = so.getCode();
        System.out.println("name:" + name + "  code: " + code);
    }
}
class Student_Object {
    private String name;
    private Integer code;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public Student_Object(String name, Integer code) {
        this.name = name;
        this.code = code;
    }
    @Override
    public String toString() {
        return "Student_Object{" + "name='" + name + '\'' + ", code=" + code + '}';
    }
}
 
代码分析:
 首先main方法中创建了Object_IS对象,对象中包含另外一个对象Student_Object (初始值: name = “张三”,code = 123);
 
 test1() 方法:
 public void test1() {
    //相当于保持快照
     Student_Object so = this.so;
     String name = so.getName();
     Integer code = so.getCode();
     System.out.println("name:" + name + "  code: " + code);
 }
 
test1中:Student_Object so = this.so; 如蓝线所示,这样即使os中的so发生了变化,也不会影响方法中下面操作该对象的值。
 
 test2() 方法:
 test2中使用的使this.so 获取当前的值,也即永远可以获取最新的值,可能会带来操作对象不一致的情况。如下: 在方法执行完this.so.getName();后,一个线程改变了this.so的“指向”,指向了一个新的对象,再执行this.so.getCode();则获取的是最新对象的值,而不是原有对象的值。
public void test2() throws InterruptedException {
   String name = this.so.getName();
   //为了使问题暴漏,故意睡眠
   Thread.sleep(100);
   Integer code = this.so.getCode();
   System.out.println("name:" + name + "  code: " + code);
}
 

 按照方法test2()的执行情况,可能会出现(name = “张三”、code = 900)的情况(错误数据)。
 执行完 String name = this.so.getName();后,一个线程改变了Object_IS中so的“指向”
 ,从线1 变为了线2 ,此时就发生了同一个方法内,操作对象不一致的情况。test1()方法不会发生这种情况!


















