原理或定義
一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名 称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们 还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
结构
a.私有构造方法
b.私有静态引用指向自己实例
c.以自己实例为返回值的公有静态方法
类图
分類
1.饿汉式(常用):单例实例在类装载时就构建,急切初始化。(预先加载法)
2.懒汉式:单例实例在第一次被使用时构建,延迟初始化。
3.懒汉式-線程安全(效率不高):對比普通懒汉式加上同步關鍵字。
4.双重检测(資源利用率高):對比普通懒汉式是在第一次判斷裡面加一個同步塊,並且在同步塊里再加一次判斷。
5.静态内部类(資源利用率高):不执行getInstance()不被实例,可以执行该类其他静态方法
代码
1.饿汉式(常用):
public class Singleton {
private static Singleton uniqeInstance=new Singleton();
private Singleton(){
};
public static Singleton getInstance()
{
return uniqeInstance;
}
}
2. 懒汉式 :
public class Singleton {
private static Singleton uniqeInstance=null;
private Singleton(){
};
public static Singleton getInstance()
{
if(uniqeInstance==null)
{
uniqeInstance=new Singleton();
}
return uniqeInstance;
}
}
3. 懒汉式-線程安全(效率不高) :
public class Singleton {
private static Singleton uniqeInstance=null;
private Singleton(){
};
public static synchronized Singleton getInstance()
{
if(uniqeInstance==null)
{
uniqeInstance=new Singleton();
}
return uniqeInstance;
}
}
4. 双重检测(資源利用率高) :
public class Singleton {
private static Singleton uniqeInstance=null;
private Singleton(){
};
public static Singleton getInstance()
{
if(uniqeInstance==null)
{
synchronized(this){
if(uniqeInstance==null)
{
uniqeInstance=new Singleton();
}
}
}
return uniqeInstance;
}
}
5. 静态内部类(資源利用率高) :
public class Singleton{
private Singleton(){}
public static Singleton getInstance(){ return Holder.SINGLETON;}
private static class Holder{//内部类
private static final Singleton SINGLETON= new Singleton();
}
}
使用場景
1.资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如日志文件,应用配置。
2.控制资源的情况下,方便资源之间的互相通信。如线程池等。
優缺點
主要优点有:
1.在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就防止其它对象对自己的实例化,确保所有的对象都访问一个实例。
2.单例模式具有一定的伸缩性,类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。
3.提供了对唯一实例的受控访问。
4.由于在系统内存中只存在一个对象,因此可以 节约系统资源,当 需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能。
5.允许可变数目的实例。
6.避免对共享资源的多重占用。
缺点主要有:
1.不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。
2.由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。
3.单例类的职责过重,在一定程度上违背了“单一职责原则”。
4.滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。
什么是Java中的内存泄露
内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏。