设计模式之单例
饿汉式
1 , 私有化构造方法
2, 初始化实例 ,值为实例对象
3, 静态工厂方法
package com.atguigu.shejimoshi.single;
/**
*
* 饿汉式 ,上来就new
*/
public class Singleton {
/**
* 私有化构造方法
*/
private Singleton(){ }
// 初始值为实例对象
private static Singleton singleton = new Singleton();
/**
* 静态工厂方法
* @return
*/
public static Singleton getInstance(){
return singleton;
}
public static void main(String[] args) {
// 获取单例对象
Singleton instance = Singleton.getInstance();
}
}
懒汉式
懒汉式和饿汉式的步骤基本相似, 不同之处是初始化的时候懒汉式初始化值为null,在调用获取实例方法的时候判断对象实例是否为null,如果为null,创建对象,如果不为null, 直接返回实例,代码如下
package com.atguigu.shejimoshi.single;
/**
*
* 饿汉式 ,上来就new
*/
public class Singleton {
/**
* 私有化构造方法
*/
private Singleton(){ }
// 初始值为实例对象
private static Singleton singleton = null;
/**
* 静态工厂方法
* @return
*/
public static Singleton getInstance(){
if (singleton==null){
singleton = new Singleton();
}
return singleton;
}
public static void main(String[] args) {
// 获取单例对象
Singleton instance = Singleton.getInstance();
}
}
单例模式之线程安全
**线程安全模式对比之前的懒汉,饿汉,不同之处是在多线程的情况下是线程安全的,具体实现方法是在静态获取实例的方法上加synchronized ** ,代码如下:
package com.atguigu.shejimoshi.single;
/**
* 同步锁(解决线程安全问题):
*/
public class Singleton3 {
private Singleton3(){
System.out.println("私有化构造方法");
}
private static Singleton3 singleton3 = null;
public synchronized static Singleton3 getInstance(){
if (singleton3==null){
singleton3 = new Singleton3();
}
return singleton3;
}
public static void main(String[] args) {
/**
* 调用同步锁单例方法
*/
Singleton3 instance = Singleton3.getInstance();
}
}
单例之双重检查锁(提高同步锁效率)
**双重检查锁模式是为了提高 同步锁单例的效率,双重检查锁没有在方法上加synchronized 关键字,而是在方法内部加synchronized 代码块, 主要代码如下: **
package com.atguigu.shejimoshi.single;
/**
* 双重检查锁(提高同步锁的效率):
*/
public class Singleton4 {
private Singleton4(){}
//初始化
private volatile static Singleton4 singleton4 = null ;
public static Singleton4 getInstance(){
/**
* 第一次if判断, 为了提高代码效率,因为 单例模式只能创建一个实例, 如果前面实例不为空,不用进入同步代码块
*/
if (singleton4==null){
synchronized (Singleton4.class){
/**
* 第二次校验: 也就是第二个if(singleton==null),这个校验是防止二次创建实例,假如有一种情况,当singleton还未被创建时,线程t1调用getInstance方法,由于第一次判断singleton==null,此时线程t1准备继续执行,但是由于资源被线程t2抢占了,此时t2页调用getInstance方法。
*/
if (singleton4==null){
singleton4 = new Singleton4();
}
}
}
return singleton4;
}
}