使用:
- 1.各种mgr
- 2.各种Factory
1.私有化对象 2.私有化构造器 3.公有化获取对象方法第一种:推荐使用,线程安全:
- 类加载到内存之后,就实例化一个单利,JVM保证线程安全;
- 缺点:类装载时候就会实例化
package com.fengzi.design; public class Mgr01 { private static Mgr01 mgr01 = new Mgr01(); private Mgr01(){} public static Mgr01 getInstance(){ return mgr01; } public static void main(String[] args) { System.out.println(Mgr01.getInstance()); System.out.println(Mgr01.getInstance()); } }2.lazy loading 懒汉式
- 多线程情况下会产生多个实例
package com.fengzi.design; public class Mgr02 { private static Mgr02 mgr02 ; private Mgr02(){} public static Mgr02 getInstance(){ if(mgr02 == null){ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } mgr02 = new Mgr02(); } return mgr02; } public static void main(String[] args) { for(int i = 0; i< 100;i++){ new Thread(()->{ System.out.println(Mgr02.getInstance().hashCode()); }).start(); } } }3.lazy loading :加锁,但是性能换安全
package com.fengzi.design; public class Mgr03 { private static Mgr03 mgr02 ; private Mgr03(){} public static synchronized Mgr03 getInstance(){ if(mgr02 == null){ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } mgr02 = new Mgr03(); } return mgr02; } public static void main(String[] args) { for(int i = 0; i< 100;i++){ new Thread(()->{ System.out.println(Mgr03.getInstance().hashCode()); }).start(); } } }4.lazy loading:将锁更加的细微化,加锁到需要加锁的地方
- 这种方案不可行,if判断对象多线程都会进来执行
package com.fengzi.design; public class Mgr04 { private static Mgr04 mgr02; private Mgr04() { } public static Mgr04 getInstance() { if (mgr02 == null) { synchronized (Mgr04.class) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } mgr02 = new Mgr04(); } } return mgr02; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(() -> { System.out.println(Mgr04.getInstance().hashCode()); }).start(); } } }5.双重检查+sync = 安全
package com.fengzi.design; public class Mgr05 { //防止指令重排 private static volatile Mgr05 mgr02; private Mgr05() { } public static Mgr05 getInstance() { if (mgr02 == null) { synchronized (Mgr05.class) { if (mgr02 == null) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } mgr02 = new Mgr05(); } } } return mgr02; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(() -> { System.out.println(Mgr05.getInstance().hashCode()); }).start(); } } }6.静态内部类:推荐使用,比第一种更好一点
- 静态内部类在外边类被加载的时候,是不会加载内部类
package com.fengzi.design; public class Mgr06 { private Mgr06() { } private static class Mgr06Holder{ private static final Mgr06 mgr06 = new Mgr06(); } public static Mgr06 getInstance() { return Mgr06Holder.mgr06; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(() -> { System.out.println(Mgr06.getInstance().hashCode()); }).start(); } } }7.枚举类 : 完美中的完美
- 不仅可以解决线程同步,还可以防止反序列化
package com.fengzi.design; public enum Mgr07 { INSTANCE; public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(() -> { System.out.println(Mgr07.INSTANCE.hashCode()); }).start(); } } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)