java中9种常见的单例模式

单例模式分为两大种,一种是饿汉模式,一种是懒汉模式(懒加载)

饿汉模式

1.单例-饿汉模式 占用内存常驻,静态常量直接初始化

public class Singleton01 {
    //单例-饿汉模式  占用内存常驻
    private Singleton01() {
        if(SINGLETON!=null){
            throw new RuntimeException();
        }
    }

    private static final Singleton01 SINGLETON = new Singleton01();

    public Singleton01 getInstance() {
        return SINGLETON;
    }

}

 

2.单例-饿汉模式 不占用内存常驻,采用静态内部类直接初始化

public class Singleton02 {
    //单例-饿汉模式  不占用内存常驻
    private static class Singleton02Inner {
        private static final Singleton02 SINGLETON = new Singleton02();
    }

    private Singleton02() {
        if (Singleton02Inner.SINGLETON != null) {
            throw new RuntimeException();
        }
    }

    public Singleton02 getInstance() {
        return Singleton02Inner.SINGLETON;
    }

3.采用枚举类型

public enum Singleton03 {
    //枚举实例
    SINGLETON;

    public void otherMethod() {

    }

}

 

懒汉模式(懒加载)

4.单例-懒汉模式 实现懒加载,线程不安全,多线程时,不一定只有一个实例

public class Singleton04 {
    //单例-懒汉模式 实现懒加载,线程不安全
    private static Singleton04 singleton = null;

    private Singleton04() {
        if (singleton != null) {
            throw new RuntimeException();
        }
    }

    public static Singleton04 getInstance() {
        if (singleton == null) {
            singleton = new Singleton04();
        }
        return singleton;
    }

    public static void main(String[] args) {
        System.out.println(getInstance() == getInstance());
    }

}

 

5.单例-懒汉模式 线程安全写法,但是效率不高,开销大

public class Singleton05 {
    //单例-懒汉模式   线程安全写法,但是效率不高,开销大
    private static Singleton05 singleton = null;

    private Singleton05() {
        if (singleton != null) {
            throw new RuntimeException();
        }
    }

    public static synchronized Singleton05 getInstance() {
        if (singleton == null) {
            singleton = new Singleton05();
        }
        return singleton;
    }

    public static void main(String[] args) {
        System.out.println(getInstance() == getInstance());
    }
}

 

6.单例-懒汉模式 线程不完全安全写法,效率比同步方法高,双重校验锁

public class Singleton06 {
    //单例-懒汉模式   线程不完全安全写法,效率比同步方法高,双重校验锁
    private static Singleton06 singleton = null;

    private Singleton06() {
        if (singleton != null) {
            throw new RuntimeException();
        }
    }

    public static Singleton06 getInstance() {
        if (singleton == null) {
            synchronized (Singleton06.class) {
                if (singleton == null) {
                    singleton = new Singleton06();
                }
            }
        }
        return singleton;
    }

}

 

7.单例-懒汉模式 线程安全写法,效率比同步方法高,双重校验锁升级版

public class Singleton07 {
    //单例-懒汉模式   线程安全写法,效率比同步方法高,双重校验锁升级版
    //volatile 起到禁止指令重排的作用,在它赋值完成之前,就不会调用读操作(singleton == null)。
    private static volatile Singleton07 singleton = null;

    private Singleton07() {
        if (singleton != null) {
            throw new RuntimeException();
        }
    }

    public static Singleton07 getInstance() {
        if (singleton == null) {
            synchronized (Singleton07.class) {
                if (singleton == null) {
                    singleton = new Singleton07();
                }
            }
        }
        return singleton;
    }
}

8.使用 ThreadLocal 实现(线程安全)

public class Singleton08 {
    //使用 ThreadLocal 实现(线程安全)
    //ThreadLocal 会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。
    //对于多线程资源共享的问题,
    // 同步机制采用了“以时间换空间”的方式,而ThreadLocal 采用了“以空间换时间”的方式。
    // 前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,
    // 因此可以同时访问而互不影响。
    private static final ThreadLocal<Singleton08> SINGLETON = new ThreadLocal<Singleton08>() {
        @Override
        protected Singleton08 initialValue() {
            return new Singleton08();
        }
    };

    private Singleton08() {

    }

    public static Singleton08 getInstance() {
        return SINGLETON.get();
    }
}

9.CAS锁实现,比较再交换(线程安全)

public class Singleton09 {
    //CAS锁实现,比较再交换
    private static final AtomicReference<Singleton09> SINGLETON = new AtomicReference<>();

    private Singleton09() {

    }

    public static final Singleton09 getInstance() {
        for (; ; ) {
            Singleton09 current = SINGLETON.get();
            if (current != null) {
                return current;
            }
            current = new Singleton09();
            if (SINGLETON.compareAndSet(null, current)) {
                return current;
            }
        }
    }

    public static class MyTest {
        @Test
        public void test() throws InterruptedException {
          Thread th =   new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int i = 0; i < 100000; i++) {
                            long i1 =  i ^ 5;
                            System.out.println(i1);
                        }
                        System.out.println("aaaa");
                        notifyAll();
                        Thread.currentThread().sleep(10000);

                        System.out.println("fdsafsa");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
          th.start();
          th.join();
          System.out.println("woshitest");

        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章