java - Builder设计模式,在多线程环境中返回null

标签 java design-patterns

我在这里阅读有关该模式的内容:

https://www.geeksforgeeks.org/builder-pattern-in-java/

最后一部分演示了如何使用该模式,我尝试将代码复制到我的 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 而不是学生对象之一?

最佳答案

在您的代码中,主线程在学生接收者执行代码之前执行。

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);
}

关于java - Builder设计模式,在多线程环境中返回null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58523569/

相关文章:

.net - 在 M-V-VM 中,我的代码在哪里?

ruby-on-rails - 将 Rails 与 Comet 服务器集成的设计模式

java - 如何使 JNI RegisterNatives callack Java 函数具有 C++ 实例范围?

java - 使用数据库服务自动配置在 IBM/Bluemix 上启动 java 应用程序时出错

java - Windows - 在Java程序中使用set和echo

java - 获取 FreeMarker 上 URL 的查询字符串

java - 强制一步步构建对象

java - Java 中的 AFOAuth2Client 等价物

sql - 您应该使用单表继承还是在一个 View 中联合使用多个表?

java - 工厂模式是正确的模式吗?