如何写一个简单的单例模式?

如何写一个简单的单例模式?
2025-01-04 04:00:02
推荐回答(5个)
回答1:

一、基本的实现思路:

单例的实现主要是通过以下两个步骤:

1、将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;

2、在该类内提供一个静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。

二、示范如下:

1、枚举实现单例:

2、懒汉式线程不安全:

3、懒汉式线程安全:

4、饿汉式:

5、双重校验锁:

6、静态内部类:

扩展资料:

一、单列模式简介:

单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。

二、懒汉与饿汉:

1、懒汉方式:指全局的单例实例在第一次被使用时构建。

2、饿汉方式:指全局的单例实例在类装载时构建。

三、单例模式的三要点:

1、某个类只能有一个实例。

2、它必须自行创建这个实例。

3、它必须自行向整个系统提供这个实例。

四、优缺点:

1、优点:

①实例控制:单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。

②灵活性:因为类控制了实例化过程,所以类可以灵活更改实例化过程。

2、缺点:

①开销:虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。

②可能的开发混淆:使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。

③对象生存期:不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。

参考资料:百度百科单列模式

回答2:

单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局的提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。

代码具体写法主要有以下两种方法:

1、饿汉式

public class Singleton1 {

private Singleton1() {};//私有的无参构造器

private static Singleton1 instance = new Singleton1();    

private static Singleton1 getInstance(){        

return instance;
}
}

使用起来简单方便,但是在单例较多的情况下内存占用会比较高。

2、懒汉式

public class Singleton2 {    private Singleton2(){};    

private volatile static Singleton2 instance;//加上volite防止指令重排

private static Singleton2 getInstance(){if (instance == null) {      

synchronized(Singleton2.class){//加锁防止多线程生成多个实例

if (instance == null) {

instance = new Singleton2();//指令重排序,先完成赋值,但构造函数还没执行完

}

}

}        return instance;

}

}

采用了双重检查,线程安全

扩展资料:

单例模式的主要特点是“三私一公”:

1、需要一个保存类的唯一实例的私有静态成员变量

2、构造函数必须声明为私有的,防止外部程序new一个对象从而失去单例的意义

3、克隆函数必须声明为私有的,防止对象被克隆必须提供一个访问这个实例的公共静态方法(通常命名为getInstance),从而返回唯一实例的一个引用。

参考资料:百度百科-单例模式





回答3:

简单的单例模式如下

[java]view plaincopyprint?

public class Singleton{

private static Singleton unique Instance=null;

private Singleton(){

//Exists only to defeat instantiation.

}

public static Singleton getInstance(){

if(unique Instance==null){

unique Instance=new Singleton();

}

return unique Instance;

}

//Other methods...

}

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。

每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。

总之,选择单例模式就是为了避免不一致状态,避免政出多头。

扩展资料

一、单例模式有以下特点:

1、单例类只能有一个实例。

2、单例类必须自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

二、单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。

1.饿汉式单例类

[java]view plaincopyprint?

//饿汉式单例类.在类初始化时,已经自行实例化

public class Singleton1{

//私有的默认构造子

private Singleton1(){}

//已经自行实例化

private static final Singleton1 single=new Singleton1();

//静态工厂方法

public static Singleton1 getInstance(){

return single;

}

}

2.懒汉式单例类

[java]view plaincopyprint?

//懒汉式单例类.在第一次调用的时候实例化

public class Singleton2{

//私有的默认构造子

private Singleton2(){}

//注意,这里没有final

private static Singleton2 single=null;

//静态工厂方法

public synchronized static Singleton2 getInstance(){

if(single==null){

single=new Singleton2();

}

return single;

}

}

3.登记式单例类

[java]view plaincopyprint?

import java.util.HashMap;

import java.util.Map;

//登记式单例类.

//类似Spring里面的方法,将类名注册,下次从里面直接获取。

public class Singleton3{

private static Mapmap=new HashMap();

static{

Singleton3 single=new Singleton3();

map.put(single.getClass().getName(),single);

}

//保护的默认构造子

protected Singleton3(){}

//静态工厂方法,返还此类惟一的实例

public static Singleton3 getInstance(Stringname){

if(name==null){

name=Singleton3.class.getName();

System.out.println("name==null"+"--->name="+name);

}

if(map.get(name)==null){

try{

map.put(name,(Singleton3)Class.forName(name).newInstance());

}catch(InstantiationExceptione){

e.printStackTrace();

}catch(IllegalAccessExceptione){

e.printStackTrace();

}catch(ClassNotFoundExceptione){

e.printStackTrace();

}

}

returnmap.get(name);

}

//一个示意性的商业方法

public String about(){

return"Hello,IamRegSingleton.";

}

public static void main(String[]args){

Singleton3 single3=Singleton3.getInstance(null);

System.out.println(single3.about());

}

}

参考资料:百度百科——java单例模式

回答4:

单例模式的要点有三个;一是某各类只能有一个实例;二是它必须自行创建这个事例;三是它必须自行向整个系统提供这个实例。
单例模式有以下的特点:

1 单例类只可有一个实例。

2 单例类必须自己创建自己这惟一的实例。

3 单例类必须给所有其他对象提供这一实例。

public class EagerSingleton
{
private static final EagerSingleton m_instance =
new EagerSingleton();
/**
* 私有的默认构造子
*/
private EagerSingleton() { }
/**
* 静态工厂方法
*/
public static EagerSingleton getInstance()
{

return m_instance;
}
}

在这个类被加载时,静态变量m_instance 会被初始化,此时类的私有构造子会被调用。这时候,单例类的惟一实例就被创建出来了。

楼主可以具体参阅 阎宏博士的《Java与模式》一书的第十五章

回答5:

一般Singleton模式通常有几种形式:

public class Singleton {

private Singleton(){}

//在自己内部定义自己一个实例,是不是很奇怪?
//注意这是private 只供内部调用

private static Singleton instance = new Singleton();

//这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}

第二种形式:
public class Singleton {

private static Singleton instance = null;

public static synchronized Singleton getInstance() {

if (instance==null)
instance=new Singleton();
return instance; }

}

使用Singleton.getInstance()可以访问单态类。

上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。

一般认为第一种形式要更加安全些。