单例模式有七种写法
- 懒汉,线程不安全
- 懒汉,线程安全
- 饿汉
- 饿汉,变种
- 静态内部类
- 枚举
- 双重检验所
这里只介绍懒汉、饿汉,面试的时候经常问
单例模式的特点
- 单例类只能有一个实例
- 单例类必须自己创建自己的唯一实例
- 单例类必须给其他对象提供这一实例
懒汉模式(线程不安全)
懒汉模式,顾名思义就是懒,没有对象需要调用它的时候不去实例化,有人来向它要对象的时候再实例化对象,因为懒,比我还懒
//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton{
private Singleton() {}
private static Singleton single=null;
//静态工厂方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
也能看出来,并不能多线程使用,所以还有一个线程安全的写法
懒汉模式(线程安全)
我的理解就是,加了个关键字,对,就是那个每次都读不出来的那个词
synchronized,其实我还是能读出来的(傲娇脸)
public class Singleton {
private static Singleton single=null;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return single;
}
}
网上有些博客说,这个看着100分,很遗憾,其实效率很低,99%的情况下不需要同步
饿汉模式
饿汉模式,就是它很饿,它的对象早早的就创建好了(懒汉是有人管它要了再创建)
直接看代码
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton {
private Singleton() {}
private static final Singleton single = new Singleton();
//静态工厂方法
public static Singleton getInstance() {
return single;
}
}
这个名字起得太有学问了,因为很形象,所以很好记,但是如果面试官问起来,这么回答也是微微的有点土,下面是刚刚总结的,面试就这么答。
单例中懒汉和饿汉的本质区别在于以下几点:
①饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的。
②从实现方式来讲他们最大的区别就是懒汉式是延时加载,他是在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建,饿汉式无需关注多线程问题、写法简单明了、能用则用。但是它是加载类时创建实例(上面有个朋友写错了)、所以如果是一个工厂模式、缓存了很多实例、那么就得考虑效率问题,因为这个类一加载则把所有实例不管用不用一块创建。