1.饿汉式
//饿汉式单例模式 //可能会浪费空间 public class HungryPattern {
//构造器私有 private HungryPattern() {}; private static final HungryPattern hungryPattern = new HungryPattern(); public HungryPattern getInstance() { return hungryPattern; } }
2.懒汉式
//懒汉式在单线程的情况下是OK的 public class LazyPattern { private LazyPattern() { System.out.println(Thread.currentThread().getName()+"OK!");//最后这边输出的可能不只一个线程。 }; private static LazyPattern lazyPattern; public static LazyPattern getInstance() { if(lazyPattern == null) { lazyPattern = new LazyPattern(); } return lazyPattern; } //在多线程情况下会出现问题 public static void main(String[] args) { for(int i = 0;i<=10;i++) { new Thread(()->{ LazyPattern.getInstance(); }).start(); } } }
结果:
Thread-0OK!
Thread-1OK!
Thread-2OK!
3.解决懒汉式的问题,双重检测锁模式
public class SynchronizedSingleton { private SynchronizedSingleton() { System.out.println(Thread.currentThread().getName()+"=> OK"); } private static SynchronizedSingleton singleton; public static SynchronizedSingleton getInstance() { //双重检测锁模式 if(singleton == null) { synchronized(SynchronizedSingleton.class) {//锁的是类模板 if(singleton == null) { singleton = new SynchronizedSingleton(); } } } return singleton; } public static void main(String[] args) { for(int i = 0;i<=10;i++) { new Thread(()->{ SynchronizedSingleton.getInstance(); }).start(); } } }
4.因为指令的重排,双重检测加锁的方式还是有可能出现问题,这个时候就需要加一个volatile.
package Singleton; public class SynchronizedSingleton { private SynchronizedSingleton() { System.out.println(Thread.currentThread().getName()+"=> OK"); } private static volatile SynchronizedSingleton singleton; public static SynchronizedSingleton getInstance() { //双重判断加锁 if(singleton == null) { synchronized(SynchronizedSingleton.class) { if(singleton == null) { singleton = new SynchronizedSingleton();//不是一个原子性操作 /*1.分配内存空间 *2.执行构造方法,初始化对象 *3.把这个对象指向这个空间 *正常的执行顺序是123 *但是由于指令重排:可能编程132 *这个时候有可能还没有完成实例化,但是另外一个线程过来了就会返回一个null * *这个时候就需要对singleton对象加一个volatile 来保证指令的不重排。 */ } } } return singleton; } public static void main(String[] args) { for(int i = 0;i<=10;i++) { new Thread(()->{ SynchronizedSingleton.getInstance(); }).start(); } } }
原文:https://www.cnblogs.com/Joyce-day-day-up/p/14009948.html