15.单例模式

本文详细介绍了Java中的单例模式实现,包括懒汉式(线程不安全和线程安全版本)、饿汉式、双重检查锁定以及静态内部类和枚举方式,讨论了它们的优缺点和线程安全性保障机制。


单例模式

单例模式(Singleton Pattern) 是一种创建型设计模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点。这样的实例通常用于控制对资源的访问,例如数据库连接、线程池、日志对象等。

在单例模式中,类负责创建自己的唯一实例,并提供一个静态方法让外部代码访问该实例。

下面我们来实现单例模式。

懒汉式(线程不安全)

懒汉式是指在第一次调用 getInstance 方法时才会创建实例。这种实现方式在多线程环境下是不安全的。

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {}

    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

懒汉式(线程安全,同步方法)

在懒汉式的基础上,通过添加 synchronized 关键字来保证线程安全。但这种方式会带来性能问题,因为每次获取实例都要进行同步。

public class SynchronizedLazySingleton {
    private static SynchronizedLazySingleton instance;

    private SynchronizedLazySingleton() {}

    public static synchronized SynchronizedLazySingleton getInstance() {
        if (instance == null) {
            instance = new SynchronizedLazySingleton();
        }
        return instance;
    }
}

饿汉式(线程安全)

饿汉式是指在类加载的时候就创建实例,因此不存在多线程环境下的线程安全问题。但在类加载时就创建实例,可能造成资源浪费。

public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();

    private EagerSingleton() {}

    public static EagerSingleton getInstance() {
        return instance;
    }
}

双重检查锁定(Double-Checked Locking)

通过双重检查锁定机制,在懒汉式的基础上进行优化,提高了性能。

public class DoubleCheckedLockingSingleton {
    private static volatile DoubleCheckedLockingSingleton instance;

    private DoubleCheckedLockingSingleton() {}

    public static DoubleCheckedLockingSingleton getInstance() {
        if (instance == null) {  // 第一次检查
            synchronized (DoubleCheckedLockingSingleton.class) {
                if (instance == null) {  // 第二次检查
                    instance = new DoubleCheckedLockingSingleton();
                }
            }
        }
        return instance;
    }
}
  • 第一次检查: 主要是为了避免不必要的同步开销。当实例已经创建后,不再需要进入同步块,直接返回已创建的实例。

  • 第二次检查: 在同步块内进行创建实例的操作,如果没有第二次检查,可能会导致多个线程都通过第一次检查,进入同步块,然后其中一个线程创建了实例,而其他线程没有再次检查,也会再次创建实例,破坏了单例的原则。

  • 使用 volatile 关键字修饰 instance 变量,确保多线程环境下的可见性。在 Java 5 及以上的版本,volatile 关键字的语义已经有了明确的规定,可以保证双重检查锁定在多线程环境下的正确性。

静态内部类

通过静态内部类的方式实现单例模式,利用了类加载的机制,保证了线程安全。

public class StaticInnerClassSingleton {
    private StaticInnerClassSingleton() {}

    private static class SingletonHolder {
        private static final StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
    }

    public static StaticInnerClassSingleton getInstance() {
        return SingletonHolder.instance;
    }
}
  • 类加载时的线程安全性: 类加载过程中,当类被加载到内存中时,类初始化阶段是由 JVM 负责的,它保证了在多线程环境下,一个类只会被初始化一次。这是通过类加载器的锁机制来实现的。

  • 静态内部类的延迟加载: 静态内部类不会在外部类加载时立即被加载,而是在第一次使用时才被加载。由于类加载和初始化是线程安全的,所以静态内部类的加载也是线程安全的。

类加载机制

在 Java 中,类加载器(ClassLoader)是负责加载 Java 类的机制。类加载器的主要任务是将类的字节码加载到内存中,并转换为一个 Class 类型的对象。类加载器通过委托模型(Delegation Model)来实现对类的加载,同时采用了一些机制确保类只被初始化一次。

类加载器的工作原理:

  1. 加载(Loading): 类加载器负责将类的字节码加载到内存中。

  2. 链接(Linking): 链接阶段包括验证、准备和解析。其中,验证是确保字节码符合 Java 虚拟机规范,准备是为类的静态变量分配内存并设置默认初始值,解析是将符号引用转换为直接引用。

  3. 初始化(Initialization): 在类初始化阶段,执行类的初始化代码。这个阶段是延迟进行的,即在对类的第一次主动使用时才会触发。

为什么类加载器能够实现一个类只被初始化一次:

  1. 委派模型: Java 的类加载器采用了委派模型,即每个类加载请求都会先委派给父类加载器处理。这样可以保证同一个类不会被多个类加载器重复加载。

  2. 类初始化锁: 在类初始化阶段,类加载器会使用一个互斥锁,确保只有一个线程能够初始化该类。这样可以避免多个线程同时初始化同一个类,保证线程安全性。

  3. 初始化标记: 类加载器在完成对类的初始化后,会在内部使用一个标记,表明该类已经被初始化过。当其他类加载器尝试再次加载同一个类时,会检查这个标记,避免重复初始化。

枚举

枚举方式是 JDK 1.5 之后引入的,它天生就是线程安全的,而且可以防止反射和反序列化攻击。

public enum EnumSingleton {
    INSTANCE;

    // 可以添加其他方法和属性
}
<think>好的,我需要回答用户关于Windows查看隐藏用户的方法以及VMware虚拟机网络模式及配置类型的问题。首先,我需要分清楚这两个部分,分别处理。 对于Windows查看隐藏用户的方法,用户可能指的是系统内置的隐藏账户或者通过某些手段隐藏的用户账户。通常,Windows的本地用户和组管理工具不会直接显示隐藏账户,但可以通过命令行或者注册表来查看。记得引用相关的资料,但用户提供的引用是关于VMware虚拟机的,可能没有直接关联,所以可能需要依靠自己的知识库。 接下来是VMware虚拟机的网络模式及配置类型。用户提到的引用中有几个关于VMware网络配置的内容,比如仅主机模式、桥接模式、NAT模式等。需要整理这些模式的特点,并结合引用中的信息。例如,引用[1]提到仅主机模式通过VMnet1与宿主机通信,而引用[3]提到检查网卡配置是否正常。引用[4]则区分了Player和Pro版本的不同适用场景。 需要注意用户提供的引用可能不完全对应问题,但需要尽量结合。例如,引用[2]提到虚拟机中XP系统无法获取IP,可能与网络配置有关,但具体到网络模式可能需要解释不同模式下的IP分配情况。 在回答结构上,需要分点清晰,先回答Windows查看隐藏用户的方法,再详细说明VMware的网络模式。同时,按照用户要求,生成相关问题,并确保使用正确的LaTeX格式,比如行内公式用$...$,独立公式用$$...$$,不过这个问题中可能不太涉及数学公式,但如果有需要的话要遵循。 最后,确保回答真实可靠,引用用户提供的资料中的相关内容,比如引用[1]、[3]、[4]中的VMware网络配置部分。可能需要检查是否有遗漏的网络模式,如NAT、桥接、仅主机和自定义网络等,并解释每种模式的特点和配置方法。 现在需要组织语言,确保符合中文回答,结构清晰,分步骤说明,并在最后生成相关问题。</think>### Windows查看隐藏用户的方法 1. **通过注册表查看** 打开注册表编辑器(`regedit`),定位到以下路径: `HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names` 此处会列出所有用户账户,包括隐藏账户。需注意:默认权限可能限制访问,需手动调整权限[^1]。 2. **使用命令行工具** - **命令提示符**:执行以下命令导出用户列表: ```cmd net user > users.txt ``` 打开生成的`users.txt`文件检查异常用户。 - **PowerShell**:运行: ```powershell Get-LocalUser | Format-Table Name, Enabled, Hidden ``` 若系统支持相关模块,可显示隐藏用户状态。 3. **通过本地用户和组管理(需管理员权限)** 打开`lusrmgr.msc`,部分隐藏账户可能不会直接显示,但可通过对比注册表或命令行结果排查异常条目。 --- ### VMware虚拟机网络模式及配置类型 VMware支持以下主要网络模式,其特点如下: #### 1. **桥接模式(Bridged)** - **特点**:虚拟机通过宿主机的物理网卡直接接入外部网络,与宿主机同一网段,拥有独立IP地址[^3]。 - **适用场景**:需要虚拟机作为独立设备与局域网其他设备通信。 #### 2. **NAT模式(网络地址转换)** - **特点**:虚拟机共享宿主机的IP地址,通过虚拟NAT设备访问外部网络。外部无法直接访问虚拟机,但虚拟机可主动连接外部[^1]。 - **配置示例**: ```text 虚拟网卡:VMnet8 IP分配:由VMware DHCP服务自动分配 ``` #### 3. **仅主机模式(Host-Only)** - **特点**:虚拟机通过专用虚拟网卡(如`VMnet1`)与宿主机通信,完全隔离外部网络[^1][^3]。 - **用途**:用于构建封闭测试环境,或需要宿主机与虚拟机直接交互的场景。 #### 4. **自定义网络** - **特点**:用户可自定义虚拟交换机规则,结合上述模式实现复杂网络拓扑[^4]。 #### 配置步骤(以仅主机模式为例) 1. 打开虚拟机设置,选择网络适配器。 2. 选择“仅主机模式”,确保宿主机虚拟网卡`VMnet1`已启用[^3]。 3. 在虚拟机内配置静态IP或启用DHCP(需检查服务状态,如引用[2]中XP系统需确认网络服务是否正常)。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值