ITPub博客

首页 > 应用开发 > Java > Java 中如何实现延迟初始化?

Java 中如何实现延迟初始化?

原创 Java 作者:mingtian66 时间:2024-11-10 12:55:29 0 删除 编辑

在 Java 中,延迟初始化(Lazy Initialization)是一种在需要时才创建对象的技术,通常用于节省内存或提高性能。以下是几种实现延迟初始化的方式:
1. 懒汉式单例模式

在单例模式中,延迟初始化通常用于创建单例对象。通过这种方式,只有在第一次调用 getInstance 方法时才创建对象。

public class Singleton {
    // 延迟初始化的单例实例,初始为 null
    private static Singleton instance = null;

    // 私有构造函数,防止外部实例化
    private Singleton() {}

    // 提供获取实例的静态方法
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();  // 延迟实例化
        }
        return instance;
    }
}

2. 线程安全的懒汉式单例模式(双重检查锁定)

在多线程环境中,上述实现可能会创建多个实例。双重检查锁定(Double-Checked Locking)是一种优化,它使用 synchronized 来确保线程安全。

public class Singleton {
    // volatile 确保 instance 的修改对所有线程可见
    private static volatile Singleton instance = null;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {  // 第一次检查
            synchronized (Singleton.class) {
                if (instance == null) {  // 第二次检查
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

3. 静态内部类实现

静态内部类的方式利用了 Java 的类加载机制,只有在使用 getInstance 方法时,静态内部类才会被加载。这是一种线程安全且高效的延迟初始化方式。

public class Singleton {
    private Singleton() {}

    // 静态内部类,用于持有 Singleton 实例
    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return Holder.INSTANCE;  // 只有调用此方法时才会加载 Holder 类
    }
}

4. Lazy Initialization Holder Class 模式

这是 Java 延迟初始化的另一种推荐方式,适合构建具有复杂初始化逻辑的对象。通过在需要的时候才初始化成员变量,实现延迟初始化。

public class Resource {
    private Resource() {}

    // Resource 的延迟初始化实现
    private static class ResourceHolder {
        private static final Resource INSTANCE = new Resource();
    }

    public static Resource getInstance() {
        return ResourceHolder.INSTANCE;
    }
}

5. 使用 java.util.Optional 实现延迟初始化

Optional 在 Java 8 中被引入,可以用于延迟初始化字段。这种方式适合非单例对象的延迟初始化。

import java.util.Optional;

public class LazyInitializedObject {
    private Optional<HeavyResource> resource = Optional.empty();

    public HeavyResource getResource() {
        if (resource.isEmpty()) {
            resource = Optional.of(new HeavyResource());  // 延迟初始化
        }
        return resource.get();
    }
}

class HeavyResource {
    public HeavyResource() {
        System.out.println("HeavyResource initialized");
    }
}

6. 使用 Supplier

在 Java 8 中,可以使用 Supplier 接口进行延迟初始化。这种方式同样适用于非单例的对象延迟初始化。

import java.util.function.Supplier;

public class LazyInitializedObject {
    private Supplier<HeavyResource> resource = this::createResource;

    private HeavyResource createResource() {
        HeavyResource res = new HeavyResource();
        resource = () -> res;  // 更新 Supplier,不再创建新对象
        return res;
    }

    public HeavyResource getResource() {
        return resource.get();
    }
}

这些方式根据不同的需求和场景提供了不同的延迟初始化方案:对于单例模式,可以选择静态内部类或双重检查锁定;对于一般对象,可以使用 Optional 或 Supplier 方式。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70040412/viewspace-3048245/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2024-08-07

  • 博文量
    589
  • 访问量
    603014