java中的单体设计模式
在一个系统中维护一个对象的单一实例被称为单体设计模式。
当我们使用new Object()代码来构造一个对象时,会创建一个新的实例;但是,如果我们调用这些,会在堆内存中创建多个实例。如果对新对象的调用次数增加,堆内存中的对象的大小就会增长,造成性能开销。
为了防止这种情况,我们将为所有的调用创建一个单一的对象,并返回同一个对象。
简单的单子实现:
- 私有构造函数,仅在本类内实例化本类。
- 一个私人静态变量,是同一个类的实例
- 声明静态方法,检查静态变量,如果为空,创建一个对象,否则返回对象。
急于加载单子的例子
但是,有多种方法可以写成急于加载或懒惰加载
public class Singleton {
/*
* Initializing the static member variable as null
*/
public static Singleton single = null;
/*
* private means, we can not create any object using new operator outside
* this class
*/
private Singleton() {
}
/*
* this method always return same instance. you can make this method as
* synchronized to create amultiple isntances by different thread at a time
*/
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
/*
* clone is not supported and throws exception if we make the clone of this
* object
*
* @see java.lang.Object#clone()
*/
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException(
"This is singleton class, cloning is not supported");
}
public static void main(String args[]) {
/*
* calling the multiple getInstance method always returns the same
* instance
*/
System.out.println("Object=1 " + getInstance());
System.out.println("Object=2 " + getInstance());
}
}
懒惰初始化单子的例子
在这种情况下,单子类是懒惰地生成和初始化的,这意味着每当客户端调用getInstance方法时,它就会创建一个单一的对象并返回它:
public class SingletonClass {
private static class Loader {
static SingletonClass object = new SingletonClass();
}
private SingletonClass () {}
public static SingletonClass getInstance() {
return Loader.object;
}
}
以上所有的例子,都是在每个线程中返回单个实例,那么如何在多线程的应用程序中创建单个对象呢?
单线程安全的例子
在这种情况下,Synchronize 关键字在多线程应用程序中被使用和命名。当一个线程进入synchornize块时,它被分配了一个锁,而另一个线程则在等待完成第一个线程的任务。
这样一来,我们就可以在多个线程中实现单个对象访问实例的创建。
public class Singleton {
private static Singleton instance = null;
privat e Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
优势
这种模式在java虚拟机的堆内存中保留了一个java对象的实例,而不是创建多个实例,因此,提高了性能,减少了为堆内存创建的对象