与 Eager 相比,使用惰性初始化有什么好处吗?

Is there any benefit of using lazy initialization as compared to Eager?

何时使用惰性初始化以及何时使用 Eager,因为即使我们使用惰性,我们将使用的变量仍将包含一些与以下任务相关的数据。那么我们如何在两者之间进行选择呢?两者之间是否存在任何性能和内存效率差异?

请解释任何最佳用例,因为有些线程支持急切而有些线程支持惰性。

这里首先要讨论的是什么是延迟加载和预加载:

Eager Loading 是一种在现场进行数据初始化的设计模式 延迟加载是一种设计模式,用于尽可能推迟对象的初始化 让我们通过一些示例看看这实际上是如何工作的:

懒惰的用户class:

@Entity
@Table(name = "USER")
public class UserLazy implements Serializable {
 
    @Id
    @GeneratedValue
    @Column(name = "USER_ID")
    private Long userId;
 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    private Set<OrderDetail> orderDetail = new HashSet();
 
    // standard setters and getters
    // also override equals and hashcode
 
}

订单详情class:

@Entity
@Table (name = "USER_ORDER")
public class OrderDetail implements Serializable {
    
    @Id
    @GeneratedValue
    @Column(name="ORDER_ID")
    private Long orderId;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="USER_ID")
    private UserLazy user;
 
    // standard setters and getters
    // also override equals and hashcode
 
}

一个用户可以有多个 OrderDetails。在预加载策略中,如果我们加载用户数据,它也会加载与其关联的所有订单并将其存储在内存中。

但是,当启用延迟加载时,如果我们拉起一个 UserLazy,OrderDetail 数据将不会被初始化并加载到内存中,直到对其进行显式调用。

在下一节中,我们将看到上面的示例是如何在 Hibernate 中实现的。

在此处查找文章: https://www.baeldung.com/hibernate-lazy-eager-loading

另请阅读: https://www.imperva.com/learn/performance/lazy-loading/

总的来说,延迟加载的优点是:

  • 如果您永远不需要该值,则在加载或存储它时无需支付任何速度或内存损失。
  • 启动速度更快。

缺点是:

  • 第一次需要该值时,您必须等待它加载。
  • 以线程安全的方式访问字段通常会产生少量开销。 (这是必需的,因为您通常不希望两个不同的线程执行两次加载;并且在任何情况下您都不希望任何线程看到部分加载的数据。)

在其他语言中,另一个缺点是需要额外的代码来实现最后一点,但是 Kotlin 的 by lazy 让它变得非常简单!

显然,总体收益取决于您需要该价值的可能性有多大,以及启动延迟与以后相比的影响。