单例模式
概念:
一个系统中只有一个类的实例对象可以被获取和使用(且该实例对象是自行创建的)。单例模式分为饿汉式和懒汉式两种。
饿汉式:
直接创建实例对象,线程安全。
1. 枚举类
package com.sk.singleton;
public enum Singleton {
INSTANCE
}
2. 直接实例化(两种对外提供实例的方式)
package com.sk.singleton;
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton(){
}
}
package com.sk.singleton;
public class Singleton {
private static final Singleton instance= new Singleton();
private Singleton(){
}
public static Singleton getSingleton(){
return instance;
}
}
3.静态代码块(适用于复杂实例化)
package com.sk.singleton;
public class Singleton {
private static final Singleton instance;
private String name;
static {
instance= new Singleton("玉无双");
}
private Singleton(String name){
this.name = name;
}
public static Singleton getSingleton(){
return instance;
}
}
懒汉式
延迟创建对象,需要用时才创建
package com.sk.singleton;
/**
* *线程不安全
*
*/
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getSingleton() {
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
加锁
package com.sk.singleton;
/**
* *线程安全
*/
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getSingleton() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();//3步:1.分配内存空间 2.初始化对象 3.将对象指向刚分配的内存空间 第二步与第三步极小情况下会发生指令重排 导致返回null
}
}
}
return instance;
}
}
package com.sk.singleton;
/**
* *线程安全
* *volatile 可见性,禁止指令重排
*/
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getSingleton() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
静态内部类形式
package com.sk.singleton;
/**
* *线程安全
* *静态内部类不会随着外部类的加载和初始化而初始化
*/
public class Singleton {
private Singleton() {
}
private static class Inner{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getSingleton(){
return Inner.INSTANCE;
}
}
jdk里的单例
- Runtime类
- GraphicsEnvironment抽象类
总结
- 构造器私有化
- 一个静态变量来保存这个唯一的实例
- 向外提供获取这个实例的方式