使用同步机制解决单例模式中的懒汉式的线程安全问题

  1 package day2_4;
  2 
  3 import org.junit.Test;
  4 
  5 /**
  6  * 单例设计模式
  7  * 1.1是什么
  8  * 就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例
  9  * 1.2 好处
 10  * 由于单例模式只生成一个实例,减少了系统性能的开销,当一个对象的产生需要比较多的资源
 11  * 时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时产生一个单例对象,然后永久
 12  * 驻留内存的方式来解决
 13  * <p>
 14  * 2.如何实现?
 15  * 饿汉式 vs 懒汉式
 16  * <p>
 17  * 3.区别
 18  * 饿汉式:(可以看看Runtime源码)
 19  * 坏处:提前把对象就创建好了,但是有可能很久才会用,或者一直也用不上,就导致对象加载时间过长
 20  * 好处:线程安全的
 21  * 懒汉式:
 22  * 坏处:需要使用同步机制解决线程安全的问题
 23  * 好处:延迟对象的创建,什么时候用就什么时候创建
 24  */
 25 public class SingletonTest {
 26     @Test
 27     public void test1() {
 28         Bank bank1 = Bank.getInstance();
 29         Bank bank2 = Bank.getInstance();
 30         System.out.println(bank1);
 31         System.out.println(bank2);
 32         System.out.println(bank2 == bank1);
 33     }
 34 
 35     @Test
 36     public void test2() {
 37         Order Order1 = Order.getInstance();
 38         Order Order2 = Order.getInstance();
 39         System.out.println(Order1);
 40         System.out.println(Order2);
 41         System.out.println(Order2 == Order2);
 42     }
 43 }
 44 
 45 //饿汉式(不管你用不用提前就创建好对象)
 46 class Bank {
 47     //2.内部创建类的对象
 48     //4.要求此对象也必须声明为静态的(为了步骤3调用)
 49     private static Bank instance = new Bank();
 50 
 51     //1.私有化类的构造器
 52     private Bank() {
 53     }
 54 
 55     //3.提供公共的静态方法,返回类的对象
 56     public static Bank getInstance() {
 57         return instance;
 58     }
 59 }
 60 
 61 //懒汉式(用的时候才创建对象) 有线程安全问题
 62 //class Order{
 63 //
 64 //    private static Order instance = null;
 65 //
 66 //    private Order(){
 67 //    }
 68 //
 69 //    public static Order getInstance() {
 70 //        if (instance == null) {
 71 //            instance = new Order();
 72 //        }
 73 //        return instance;
 74 //    }
 75 //}
 76 
 77 //懒汉式(用的时候才创建对象) 需要解决线程安全问题
 78 class Order {
 79     private static Order instance = null;
 80 
 81     private Order() {
 82 
 83     }
 84 
 85     //方式一:同步的静态方法,同步监视器是Order的类对象Order.class
 86 //    public static synchronized Order getInstance() {
 87 //        if (instance == null) {
 88 //            instance = new Order();
 89 //        }
 90 //        return instance;
 91 //    }
 92 
 93     //方式二:同步代码块(Surround With(Ctrl+Alt+T快捷键 ))
 94 //    public static synchronized Order getInstance() {
 95 //        synchronized (Order.class) {
 96 //            if (instance == null) {
 97 //                instance = new Order();
 98 //            }
 99 //            return instance;
100 //        }
101 //    }
102 
103     //上面两种方式都是正确的,但效率低点
104     //方式三:如果同步代码块中需要执行的操作比较多,下面的方式效率会高些
105     public static synchronized Order getInstance() {
106         //第一批第一个进入同步代码块的线程会不受干扰的创建对象,并返回这个对象
107         //后一批的线程在判断instance == null为false后,都不会再加入同步
108         // 代码块,这样效率更高!
109         if (instance == null) {
110             synchronized (Order.class) {
111                 if (instance == null) {
112                     instance = new Order();
113                 }
114             }
115         }
116         return instance;
117     }
118 }
原文地址:https://www.cnblogs.com/zui-ai-java/p/14378749.html