多线程下的立即加载与延迟加载

Posted allenstarkx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程下的立即加载与延迟加载相关的知识,希望对你有一定的参考价值。

一、概念释义

立即加载:也称为“饿汉模式”,就是使用类之前就已经将对象创建完毕,常见的方法就是将对象静态创建
延迟加载:也称为“懒汉加载”,就是在使用到的时候才进行创建,常见的方法为通过get()方法进行实例化。

二、具体例子

以下例子关于单例模式方法以及线程实现方法采取内部类实现

  1. 立即加载/饿汉模式:
      public class singleton_imme {
    
        //单例模式实现方式
        private static class TestObject{
            private static TestObject testObject = new TestObject();
    
            private TestObject(){
            }
    
            public static TestObject getInstance(){
                return testObject;
            }
        }
    
        //编写线程输入实例的哈希值
        private static class TestThread extends Thread{
            @Override
            public void run() {
                System.out.println(TestObject.getInstance().hashCode());
            }
        }
    
        public static void main(String[] args) {
            TestThread t1 = new TestThread();
            TestThread t2 = new TestThread();
            TestThread t3 = new TestThread();
    
            t1.start();
            t2.start();
            t3.start();
          }
      } 
    

运行结果:技术图片

立即加载通过getInstance()返回静态对象,容易理解这里不过多描述。
2. 延迟加载/懒汉模式
关于延迟模式加载,往往伴随着着线程安全与运行效率的对比沟通。关于这一块网上相当多的博客已进行讨论过,这里不在进行延伸。仅沟通目前常见的方法——DCL双检查锁机制。下面是具体例子:

  public class singleton_delay {
  
      //DCL双检查锁机制
      private static class TestObject{
          private volatile static TestObject testObject;
  
          private TestObject(){
          }
  
          public static TestObject getInstance(){
              if (testObject == null){
                  synchronized(TestObject.class){
                      if (testObject == null){
                          testObject = new TestObject();
                      }
                  }
              }
              return testObject;
          }
      }
  
      private static class TestThread extends Thread{
          @Override
          public void run() {
              System.out.println(TestObject.getInstance().hashCode());
          }
      }
  
      public static void main(String[] args) {
          TestThread[] threadList = new TestThread[10];
  
          for (TestThread th: threadList) {
              th = new TestThread();
              th.start();
          }
      }
  
  }

运行结果:技术图片

DCL双检查锁机制是通过双重监测对象是否为空,第一重锁不加线程锁,这样在多线程中进行判断,不会因为线程锁锁而降低效率。第二层时加上对应线程锁,避免出现线程安全问题。




以上是关于多线程下的立即加载与延迟加载的主要内容,如果未能解决你的问题,请参考以下文章

多线程下单例模式:懒加载(延迟加载)和即时加载

Hibernate-延迟加载和立即加载

NHibernate之(13):初探立即加载机制

Hibernate检索策略之延迟加载和立即加载

JAVA_多线程_单例模式

Mybatis从入门到精通系列 11——Mybatis 延迟加载与立即加载