设计模式day2-单例
只能存在一个对象实例
八种写法:
考虑方面 :资源使用、线程安全、效率
推荐使用:双重检查、静态内部类、枚举
一定条件下推荐使用:饿汉式
使用场景:频繁的创建和销毁对象;创建对象时耗时过多或耗费资源过多;工具类、频繁访问数据库或文件
1.饿汉式(静态常量)
/*
1.构造函数私有化
2.类内部创建对象
3.对外暴露一个静态的公共方法 getInstance
优点:类加载的时候就完成实例化,避免线程同步问题
缺点:从未使用的情况,会造成内存的浪费
确定单例一定会被用到,也推荐使用
*/
public class Singlenton1 {
//构造函数私有化
private Singlenton1(){}
//静态变量
private static final Singlenton1 instance= new Singlenton1();
//静态公共方法
public static Singlenton1 getInstance(){
return instance;
}
}
2.饿汉式(静态代码块)
/*
静态代码块
优缺点同上
确定单例一定会被用到,也推荐使用
*/
public class Singlenton2 {
//构造函数私有化
private Singlenton2(){}
//静态变量
private static Singlenton2 instance;
//静态代码块
static {
instance = new Singlenton2();
}
//静态公共方法
public static Singlenton2 getInstance(){
return instance;
}
}
3.懒汉式(线程不安全)
/*
实例用的时候才创建,只能在单线程下使用
实际开发中不使用
*/
public class Singlenton3 {
//构造函数私有化
private Singlenton3() {
}
//静态变量
private static Singlenton3 instance;
//静态公共方法
public static Singlenton3 getInstance() {
if (instance == null) {
instance = new Singlenton3();
}
return instance;
}
}
4.懒汉式(线程安全,同步方法)
/*
加入了同步处理代码
每次执行getInstance()方法都要进行同步,效率低,不推荐使用
*/
public class Singlenton4 {
//构造函数私有化
private Singlenton4() {
}
//静态变量
private static Singlenton4 instance;
//静态公共方法
public static synchronized Singlenton4 getInstance() {
if (instance == null) {
instance = new Singlenton4();
}
return instance;
}
}
5.懒汉式(线程不安全,同步代码块)
/*
线程不安全,会产生多个实例
*/
public class Singlenton4 {
//构造函数私有化
private Singlenton4() {
}
//静态变量
private static Singlenton4 instance;
//静态公共方法
public static Singlenton4 getInstance() {
if (instance == null) {
synchronized (Singlenton4.class){
instance = new Singlenton4();
}
}
return instance;
}
6.双重检查
/*
推荐使用
volatile:轻量级同步锁
*/
public class Singlenton6 {
//构造函数私有化
private Singlenton6() {
}
//静态变量
private static volatile Singlenton6 instance;
//静态公共方法
public static Singlenton6 getInstance() {
if (instance == null) {
synchronized (Singlenton6.class) {
if (instance == null) {
instance = new Singlenton6();
}
}
}
return instance;
}
}
7.静态内部类
/*
采用了类装载的机制来保证初始化实例只有一个进程
静态内部类特点:
1.外部类被装载时,静态内部类不会被装载
2.调用静态内部类时才被装载(JVM装载类时线程安全的),而且只会加载一次
特点:私有静态内部类里有一个静态属性
推荐使用
*/
public class Singlenton7 {
//构造函数私有化
private Singlenton7() {
}
//静态内部类里有一个静态属性
private static class SingletonInstance{
public static final Singlenton7 INSTANCE = new Singlenton7();
}
//静态公共方法
public static Singlenton7 getInstance() {
return SingletonInstance.INSTANCE;
}
}
8.枚举
/*
不仅能避免多线程同步问题,还能防止反序列化重写创建新的对象
推荐使用
*/
public enum Singlenton8 {
INSTANCE;
public void test(){
System.out.println("test");
}
}
JDK内单例模式:java.lang.Runtime (饿汉模式)
public class Runtime {
private static Runtime currentRuntime = new Runtime();
/**
* Returns the runtime object associated with the current Java application.
* Most of the methods of class <code>Runtime</code> are instance
* methods and must be invoked with respect to the current runtime object.
*
* @return the <code>Runtime</code> object associated with the current
* Java application.
*/
public static Runtime getRuntime() {
return currentRuntime;
}
/** Don't let anyone else instantiate this class */
private Runtime() {}
以此纪念陪伴我十年的狗狗