单例模式是面试中最常被问到的地方,那么如何理解单例模式呢?
单例模式的特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例在写法上又分为懒汉模式(线程安全,线程不安全)、饿汉模式(天生线程安全)、双重校验锁等常见写法。
但是最后会发现所有的单例模式都是static关键字进行修饰的方法,为什么呢?因为static是所有线程共享的区域,具体可以了解下JVM内存相关知识。
懒汉模式怎么理解呢?
就是很懒,在每次调用的时候才去实例化,也可以理解为:在类加载时不进行初始化。
饿汉模式怎么理解呢?
就是在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快(已经初始化好了,所以快)。
一:懒汉模式,线程不安全
/**
* 单例一 懒汉,线程不安全
* @author kobe
*
*/
public class SingletonDemo01 {
private static SingletonDemo01 instance;
private SingletonDemo01() {
}
public static SingletonDemo01 getInstance(){
if (instance == null) {
instance = new SingletonDemo01();
}
return instance;
}
}
二:懒汉模式,线程安全(用 synchronized确保安全)
/**
* 单例二 懒汉 线程安全
* @author kobe
*
*/
public class SingletonDemo02 {
private static SingletonDemo02 instance;
private SingletonDemo02() {
}
public static synchronized SingletonDemo02 getInstance() {
if(instance == null) {
instance = new SingletonDemo02();
}
return instance;
}
}
三:饿汉模式,线程天生安全
/**
* 饿汉模式
* @author kobe
*
*/
public class SingletonDemo03 {
private static SingletonDemo03 instance = new SingletonDemo03();
private SingletonDemo03() {
}
public static SingletonDemo03 getInstance() {
return instance;
}
}
四:懒汉模式,线程安全 (方式二的变种,需要在JDK1.5以后才能这样使用)
/**
* 单例四 双重校验锁
* @author kobe
*
*/
public class SingletonDemo04 {
private volatile static SingletonDemo04 instance;
private SingletonDemo04() {
}
public static SingletonDemo04 getInstance() {
if (instance == null) {
synchronized (SingletonDemo04.class) {
if(instance == null) {
instance = new SingletonDemo04();
}
}
}
return instance;
}
}