Java 生成器设计模式,在多线程环境中返回null
我在这里读到了关于模式的内容: 最后一部分演示了如何使用该模式,我尝试将代码复制到IDE中并运行它,但它返回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) {
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完成。