Singleton 单例模式
Posted nedrain
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Singleton 单例模式相关的知识,希望对你有一定的参考价值。
Singleton: Make sure that there can be "only one instance" of a Class
The Singleton class only provide a "static method" to get its object
for example: SessionFactory in Hibernate
饿汉式(静态常量)
public class SingletonTest01 {
public static void main(String[] args){
Singleton singleton = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton == singleton2); // true
}
}
class Singleton{
private Singleton(){ //private the constructor
}
private static final Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
装载类的时候,这个类就有了, 避免了线程同步的问题
但同时加载过早可能会造成浪费
饿汉式(静态代码块)
class Singleton{
private Singleton(){} //private the constructor
private static Singleton instance;
static{
instance = new Singleton(); // ********
}
public static Singleton getInstance(){
return instance;
}
}
与静态变量法优缺点相同。
懒汉式(线程不同步)
public class SingletonTest03 {
public static void main(String[] args){
SingletonLazy singleton = SingletonLazy.getInstance();
SingletonLazy singleton2 = SingletonLazy.getInstance();
System.out.println(singleton == singleton2); // true
System.out.println(singleton.hashCode());
System.out.println(singleton2.hashCode());
}
}
class SingletonLazy{
private static SingletonLazy instance;
private SingletonLazy(){};
// create instance only when called
public static SingletonLazy getInstance(){
if(instance == null){
instance = new SingletonLazy();
}
return instance;
}
}
这个肯定不适合多线程,因为 if(instance == null) 这句 没有锁。
懒汉式(线程安全)
class SingletonLazy{
private static SingletonLazy instance;
private SingletonLazy(){};
// create instance only when called
public static synchronized SingletonLazy getInstance(){
if(instance == null){
instance = new SingletonLazy();
}
return instance;
}
}
但这种方式效率太低,而且getInstance()方法实际上只需执行一次。 NOT RECOMMENDED
懒汉式 (双重检查)
class SingletonVolatile{
private static volatile SingletonVolatile singleton;
private SingletonVolatile(){};
public static SingletonVolatile getInstance(){
if(singleton == null){
synchronized(SingletonVolatile.class){
if(singleton == null){ // make sure the "null" condition is in the synchronized block
singleton = new SingletonVolatile()
}
}
}
return singleton;
}
}
静态内部类 (既 懒汉 又 线程安全 : 因为静态内部类只有在调用时才加载,仅在需要在实例化时才加载并实例化, 而类的静态属性只会在第一次加载类的时候初始化)
class SingletonInnerClass{
private SingletonInnerClass(){};
private static class SingletonInstance{
private static final SingletonInnerClass INSTANCE = new SingletonInnerClass();
} // final可以在底层进行优化
public static SingletonInnerClass getInstance(){
return SingletonInstance.INSTANCE;
}
}
枚举法 RECOMMENDED
public class SingletonTest04{
public static void main(String[] args){
SingletonEnum singleton1 = SingletonEnum.INSTANCE;
SingletonEnum singleton2 = SingletonEnum.INSTANCE;
System.out.println(singleton1 == singleton2); //true
}
enum SingletonEnum{
INSTANCE;
public void method(){
// here is your code
}
}
}
以上是关于Singleton 单例模式的主要内容,如果未能解决你的问题,请参考以下文章