IT源码网

单例模式的几种实现方式讲解

developer 2020年09月30日 编程语言 266 0
方式一、
/** 
 * 饿汉式 
 * 类加载到内存后,就实例化一个单例,JVM保证线程安全 
 * 简单实用,推荐使用! 
 * 唯一缺点:类装载时就完成实例化 
 */ 
public class Singleton01{
    
    private static final Singleton01 INSTANCE = new Singleton01 (); 
 
    private Singleton01() {
   }; 
 
    public static Singleton01 getInstance() {
    
        return INSTANCE; 
    } 
 
	/** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        Singleton01 s1= Singleton01.getInstance(); 
        Singleton01 s2= Singleton01.getInstance(); 
        System.out.println(s1== s2); 
    } 
} 

方式二

/** 
 * 同方式一 
 */ 
 
public class Singleton02 {
    
    private static final Singleton02 INSTANCE; 
    static {
    
        INSTANCE = new Singleton02(); 
    } 
 
    private Singleton02 () {
   }; 
 
    public static Singleton02  getInstance() {
    
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        Singleton02 s1 = Singleton02 .getInstance(); 
        Singleton02 s2 = Singleton02 .getInstance(); 
        System.out.println(s1 == s2); 
    } 
} 

方式三

/** 
 * lazy loading 
 * 也称懒汉式 
 * 多线程下并不能保证单例 
 */ 
public class Singleton03{
    
    private static Singleton03 INSTANCE; 
 
    private Singleton03 () {
    
    } 
 
    public static Singleton03 getInstance() {
    
        if (INSTANCE == null) {
    
            try {
    
                Thread.sleep(1); 
            } catch (InterruptedException e) {
    
                e.printStackTrace(); 
            } 
            INSTANCE = new Singleton03(); 
        } 
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()-> 
                System.out.println(Singleton03.getInstance().hashCode()) 
            ).start(); 
        } 
    } 
} 

方式四

/** 
 * lazy loading 
 * 也称懒汉式 
 * 通过synchronized 实现多线程下保证单例 
 *  
 */ 
public class Singleton04{
    
    private static Singleton04 INSTANCE; 
 
    private Singleton04() {
    
    } 
 
    public static synchronized Singleton04 getInstance() {
    
        if (INSTANCE == null) {
    
            try {
    
                Thread.sleep(1); 
            } catch (InterruptedException e) {
    
                e.printStackTrace(); 
            } 
            INSTANCE = new Singleton04(); 
        } 
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton04.getInstance().hashCode()); 
            }).start(); 
        } 
    } 
} 

方式五

/** 
 * lazy loading 
 * 也称懒汉式 
 * 减少synchronized代码块以提高效率,但多线程下不能保证单例 
 *  
 */ 
public class Singleton05 {
    
    private static Singleton05 INSTANCE; 
 
    private Singleton05 () {
    
    } 
 
    public static Singleton05 getInstance() {
    
        if (INSTANCE == null) {
    
            synchronized (Singleton05.class) {
    
                try {
    
                    Thread.sleep(1); 
                } catch (InterruptedException e) {
    
                    e.printStackTrace(); 
                } 
                INSTANCE = new Singleton05 (); 
            } 
        } 
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton05.getInstance().hashCode()); 
            }).start(); 
        } 
    } 
} 

方式六

/** 
 * lazy loading 
 * 也称懒汉式 
 * 双重检查保证多线程下单例 
 * 推荐使用 
 */ 
public class Singleton06 {
    
    private static volatile Singleton06 INSTANCE;  
 
    private Singleton06 () {
    
    } 
 
    public static Singleton06 getInstance() {
    
        if (INSTANCE == null) {
    
            //双重检查 
            synchronized (Singleton06.class) {
    
                if(INSTANCE == null) {
    
                    try {
    
                        Thread.sleep(1); 
                    } catch (InterruptedException e) {
    
                        e.printStackTrace(); 
                    } 
                    INSTANCE = new Singleton06(); 
                } 
            } 
        } 
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton06.getInstance().hashCode()); 
            }).start(); 
        } 
    } 
} 

方式七

/** 
 * 静态内部类方式 
 * JVM保证单例 
 * 加载外部类时不会加载内部类,这样可以实现懒加载 
 * 推荐使用 
 */ 
public class Singleton07 {
    
 
    private Singleton07 () {
    
    } 
 
    private static class Singleton07Holder {
    
        private final static Singleton07 INSTANCE = new Singleton07(); 
    } 
 
    public static Singleton07 getInstance() {
    
        return Singleton07Holder.INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton07.getInstance().hashCode()); 
            }).start(); 
        } 
    } 
} 

方式八

/** 
 * 枚举单例,JAVA 大神推荐 
 * 不仅可以解决线程同步,还可以防止反序列化,语义上不太符合业务,酌情使用 
 */ 
public enum Singleton08 {
    
 
    INSTANCE; 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton08.INSTANCE.hashCode()); 
            }).start(); 
        } 
    } 
} 
发布评论

分享到:

IT源码网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

postgresql查看死锁及解决方法讲解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。