Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 生成器设计模式,在多线程环境中返回null_Java_Design Patterns - Fatal编程技术网

Java 生成器设计模式,在多线程环境中返回null

Java 生成器设计模式,在多线程环境中返回null,java,design-patterns,Java,Design Patterns,我在这里读到了关于模式的内容: 最后一部分演示了如何使用该模式,我尝试将代码复制到IDE中并运行它,但它返回null 守则: final class Student { // final instance fields private final int id; private final String name; private final String address; public Student(Builder builder) {

我在这里读到了关于模式的内容:

最后一部分演示了如何使用该模式,我尝试将代码复制到IDE中并运行它,但它返回null

守则:

 final class Student {

    // final instance fields
    private final int id;
    private final String name;
    private final String address;

    public Student(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.address = builder.address;
    }

    // Static class Builder
    public static class Builder {

        /// instance fields
        private int id;
        private String name;
        private String address;

        public static Builder newInstance() {
            return new Builder();
        }

        private Builder() {
        }

        // Setter methods
        public Builder setId(int id) {
            this.id = id;
            return this;
        }

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setAddress(String address) {
            this.address = address;
            return this;
        }

        // build method to deal with outer class
        // to return outer instance
        public Student build() {
            return new Student(this);
        }
    }

    @Override
    public String toString() {
        return "id = " + this.id + ", name = " + this.name + ", address = " + this.address;
    }
}

// Client Side Code 
class StudentReceiver {

    // volatile student instance to ensure visibility
    // of shared reference to immutable objects
    private volatile Student student;

    public StudentReceiver() {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                student = Student.Builder.newInstance().setId(1).setName("Ram").setAddress("Noida").build();
                System.out.println(student.toString());
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                student = Student.Builder.newInstance().setId(2).setName("Shyam").setAddress("Delhi").build();
                System.out.println(student.toString());
            }
        });

        t1.start();
        t2.start();
    }

    public Student getStudent() {
        return student;
    }
}

// Driver class 
public class BuilderDemo {
    public static void main(String args[]) {
        StudentReceiver sr = new StudentReceiver();
        System.out.println("sr " + sr.getStudent());
    }
}

当我删除线程并在没有线程的情况下运行它时,有人知道为什么它返回null而不是一个student对象吗

在代码中,主线程在student receiver执行代码之前执行

Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
        student = Student.Builder.newInstance().setId(1).setName("Ram").setAddress("Noida").build();
        System.out.println(student.toString());
    }
});

t1.start(); // It starts, but the runnable itself has not run yet!
因此,首先,您获得
null
的学生并将其打印在main中,然后
StudentReceiver
将初始化您的学生

建议,不要在现实世界的任务中这样做,而是为了学习而这样做

或者,您可以等待用户初始化。这是一种方法

try {
    t1.join();
    t2.join();
} catch (Exception e) {
    throw new RuntimeException("Handle it properly.", e);
}

因为当你得到这个学生时,所有的线程都还没有执行。为什么不呢?创建StudentReceiver时t1.start();&t2.start();调用表示线程正在运行,对吗?好的,没关系,线程的速度不够快,无法在打印之前实例化所有内容,我在StedentReceiver实例化后进行了睡眠&它确实起作用。join()等待主线程完成StudentReceiver对象,对吗?或者如果需要初始化student对象一次,无论是在线程1还是线程2中,都可以使用带有双重检查Yes的
synchronized
部分,join使主线程等待t1和t2完成。