线程:延迟初始化与静态延迟初始化 [英] Threading : Lazy Initialization vs Static Lazy Initialization

查看:51
本文介绍了线程:延迟初始化与静态延迟初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在观看 Java 内存模型视频演示,作者说与 Lazy Initialization 相比,使用 Static Lazy Initialization 更好,但我不清楚他的意思想说.

I am going through Java Memory Model video presentation and author is saying it is better to use Static Lazy Initialization compared to Lazy Initialization and I do not clear understand what he wants to say.

我想接触社区,如果有人能用简单的 Java 代码示例解释 Static Lazy InitializationLazy Initialization 之间的区别,我将不胜感激.

I wanted to reach to community and would appreciate if someone can explain difference between Static Lazy Initialization and Lazy Initialization with simple java code example.

参考:高级编程主题 - Java 内存模型

推荐答案

两种实现都可以是静态的,所以这是第一个误解.此视频中的演示者正在解释如何利用类初始化的线程安全性.

Well both implementations can be static so that is the first misunderstanding. The presenter in this video is explaining how you can exploit the thread-safety of class initialization.

类初始化本质上是线程安全的,如果您可以在类初始化时初始化对象,则对象创建也是线程安全的.

Class initialization is inherently thread-safe and if you can have an object initialized on class initialization the object creation too are thread-safe.

这是一个线程安全的静态初始化对象的例子

Here is an example of a thread-safe statically initialized object

public class MySingletonClass{

   private MySingletonClass(){

   }
   public static MySingletonClass getInstance(){
         return IntiailizationOnDemandClassholder.instance;
   }

   private static class IntiailizationOnDemandClassHolder{
         private static final MySingletonClass instance = new MySingletonClass();

   }

}

这里需要了解的重要一点是,在调用 getInstance() 之前,永远不会创建和/或初始化 MySingletonClass 实例变量.同样,由于类初始化是线程安全的,IntiailizationOnDemandClassholderinstance 变量将被安全加载一次,并且对所有线程可见.

What is important to know here, MySingletonClass instance variable will never be created and or initialized until getInstance() is invoked. And again since class initialization is thread-safe the instance variable of IntiailizationOnDemandClassholder will be loaded safely, once and is visible to all threads.

回答您的编辑取决于您的其他类型的实现.如果您想进行双重检查锁定,您的实例变量需要是可变的.如果您不想要 DCL,那么您每次都需要同步访问您的变量.下面是两个例子:

To answer your edit depends on your other type of implementation. If you want to do double-checked-locking your instance variable would need to be volatile. If you do not want DCL then you will need to synchronize access each time to your variable. Here are the two examples:

public class DCLLazySingleton{
  private static volatile DCLLazySingleton instance;

  public static DCLLazySingleton getInstace(){
     if(instance == null){
        synchronized(DCLLazySingleton.class){
            if(instance == null)
                instance=new DCLLazySingleton();
        }
     } 
     return instance;
}

public class ThreadSafeLazySingleton{
   private static ThreadSafeLazySingleton instance;

  public static ThreadSafeLazySingleton getInstance(){
     synchronized(ThreadSafeLazySingleton.class){
        if(instance == null){
            instance = new ThreadSafeLazySingleton();
        }
        return instance;
     } 

}

最后一个示例需要对实例的每个请求进行锁定获取.第二个示例需要对每次访问进行 volatile 读取(可能便宜与否,取决于 CPU).

The last example requires a lock acquisition on every request of the instance. The second example requires a volatile-read on each access (may be cheap or not, depends on the CPU).

第一个示例将始终锁定一次,而不管 CPU.不仅如此,每次读取都将是正常的,无需担心线程安全.我个人喜欢我列出的第一个例子.

The first example will always lock once regardless of the CPU. Not only that but each read will be a normal without any need to worry about thread-safety. I personally like the first example I have listed.

这篇关于线程:延迟初始化与静态延迟初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆