您的位置:首页 > 编程语言 > Java开发

Java 设计模式——单例模式详解

2017-05-02 23:26 417 查看

前言

一直在学习Android, 但是都总觉得是在造轮子, 所以还是得把java学深刻, 不然很多线程不安全的东西就会出现.

单例模式

饿汉式单例式

所谓饿汉就是在程序启动单例模式类被加载的时候, 单例模式实例就已经被创建

public class Singleton{
private static Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}


缺点: 不管是否需要都会创建这个对象实例, 但是我们总希望能够按需求做事.

懒汉式(线程不安全)

懒汉: 当程序第一次访问单例模式实例时才进行创建.

public class Singleton{
private static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}


缺点: 在多线程中不能正常工作,详情请点击: 解决单例设计模式中懒汉式线程安全问题

懒汉(线程安全)

很明显下面代码中加了一个关键字 synchronized 锁

public class Singleton{
private static Singleton singleton;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}


缺点: 虽然能在多线程正常工作, 效率太低.

静态内部类

当Singleton类被加载的时候, singleton并没有被初始化, 因为SingletonHolder类没有被主动使用,只有调用getInstance方法时才会显示加载SingletonHolder类

public class Singleton{
private static class SingletonHolder{
private static Singleton singleton = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.singleton;
}
}


注: 以上的实现方法都有两个共同缺点;都需要额外的工作来实现序列化; 可以使用反射强行调用私有构造器(可以让构造器在创建第二的实例时抛异常).

枚举

这种写法很特殊, 在实际工作中也很少见, 在Android平台是不被推荐的.

但是线程安全和防止反射强行调用构造器, 还提供了自动序列化机制.

public enum Singleton{
INSTANCE;
public void whateverMethod(){
}
}


双重检验锁

在jdk1.5之后就有了双重校验锁, 这是我觉得最好的一个方法.

public class Singleton{
private static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton==null){
synchronized(Singleton.class){
if(singleton==null){
singleton = new Singleton();
}
}
}
return singleton;
}
}


牢记

不管采用什么方式实现, 都要牢记单例的三大要点:

线程安全

延迟加载

序列化与反序列化安全

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: