单例模式有不少的变种,饿汉模式变化不大很少说java
非线程安全的懒汉模式安全
public class LazySingletonDemo { private static LazySingletonDemo instance; public static LazySingletonDemo getInstance() { if (instance == null) { instance = new LazySingletonDemo(); } return instance; } }
线程安全的懒汉模式多线程
这种状况使用场景不是不少,除非特殊的状况下,假如只是单纯的做为工具类或者存放常量这种做用的话,考虑多线程安全没有太大意义,多new出来的对象失去引用很快会被GC掉,除非一瞬间并发量爆炸,同时new了超多的对象(真遇到了那得放鞭炮)并发
1.使用synchronized工具
public class LazySingletonDemo { private static LazySingletonDemo instance; public static LazySingletonDemo getInstance() { System.out.println(Thread.currentThread().getName() + " 1"); if (instance == null) { System.out.println(Thread.currentThread().getName() + " 2"); synchronized (LazySingletonDemo.class) { System.out.println(Thread.currentThread().getName() + " 3"); if (instance == null) { System.out.println(Thread.currentThread().getName() + " 4"); instance = new LazySingletonDemo(); } } } return instance; } public static void main(String[] args) { Runnable r = new Runnable() { public void run() { LazySingletonDemo.getInstance(); } }; Thread t1 = new Thread(r, "t1"); Thread t2 = new Thread(r, "t2"); Thread t3 = new Thread(r, "t3"); Thread t4 = new Thread(r, "t4"); Thread t5 = new Thread(r, "t5"); Thread t6 = new Thread(r, "t6"); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); t6.start(); } }
输出性能
t1 1 t6 1 t6 2 t3 1 t3 2 t4 1 t4 2 t2 1 t6 3 t5 1 t1 2 t5 2 t6 4 t2 2 t5 3 t2 3 t1 3 t4 3 t3 3
能够看出,6个线程都进入了第1,2,3步骤,可是进入到new的步骤4只有一个线程线程
这里不把锁放到方法上的缘由是,每次拿实例的时候都要锁,很是影响性能,而只有开头new的时候才须要锁code
2.使用Lock对象
public class LazySingletonDemo { private static LazySingletonDemo instance; private static ReentrantLock lock = new ReentrantLock(); public static LazySingletonDemo getInstance() { System.out.println(Thread.currentThread().getName() + " 1"); if (instance == null) { System.out.println(Thread.currentThread().getName() + " 2"); try { lock.lock(); System.out.println(Thread.currentThread().getName() + " 3"); if (instance == null) { System.out.println(Thread.currentThread().getName() + " 4"); instance = new LazySingletonDemo(); } } finally { System.out.println(Thread.currentThread().getName() + " 5"); lock.unlock(); } } return instance; } public static void main(String[] args) throws InterruptedException { Runnable r = new Runnable() { public void run() { LazySingletonDemo.getInstance(); } }; Thread t1 = new Thread(r, "t1"); Thread t2 = new Thread(r, "t2"); Thread t3 = new Thread(r, "t3"); Thread t4 = new Thread(r, "t4"); Thread t5 = new Thread(r, "t5"); Thread t6 = new Thread(r, "t6"); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); t6.start(); } }
输出get
t1 1 t3 1 t6 1 t6 2 t4 1 t4 2 t2 1 t6 3 t3 2 t5 1 t5 2 t1 2 t6 4 t2 2 t6 5 t4 3 t4 5 t3 3 t3 5 t5 3 t5 5 t1 3 t1 5 t2 3 t2 5
同上
至于Synchronized和Lock的区别就不说了,网上都有