Double-checked locking

本文详细探讨了双重检查锁定(DCL)模式在实现懒加载时如何解决多线程环境下资源重复初始化的问题,并通过代码示例展示了同步机制的重要性及其实现方式。

The DCL idiom was designed to support lazy initialization, which occurs when a class defers initialization of an owned object until it is actually needed:

public class WorldCup {
 private static WorldCup instance;
 public static WorldCup getInstance(){
  if(instance == null) //A
   instance = new WorldCup(); //B
  return instance;
 }
}

You may find something wrong here.What if you try to use SomeClass in a multithreaded application? Then a race condition results: two threads(1&2) could simultaneously execute the test to see if resource is null and, as a result, initialize resource twice. When 1 run to step B, but don't over to new WorldCup(), then 2 run to step A, and detect that instance is null. Synchronization mechanism is now may help you:

public class WorldCup {
 private static WorldCup instance;

 public static WorldCup getInstance() {
  synchronized (WorldCup.class) {
   if (instance == null) // A
    instance = new WorldCup();// B
   return instance;
  }
 }
}

Unfortunately, synchronized methods run much slower -- as much as
100 times than ordinary unsynchronized methods as switching between lock and unlock. But singleton pattern doesnot need to detect every time, we can do a lazy job.This is the DCL.

public class WorldCup {
 private static WorldCup instance;

public static WorldCup getInstance() {
  if (instance == null) { //C
   synchronized (WorldCup.class) {
    if (instance == null) // A
     instance = new WorldCup();// B
   }
  }
  return instance;
 }
}

Imangine that thread1 is inside the synchronized block,executing the statement instance = new WorldCup(); while thread2 is just entering getInstance(). Below is the memory effect:
Memory for the new WorldCup object will be allocated; the constructor for WorldCup will be called, initializing the member fields of the new object. Thread2 see these events in the following order: allocate memory, assign reference the instance ,call constructor. Suppose thread B comes along after he memory has been allocated and the instance field is set, but before the constructor is called. It sees that instance is not null, skips the synchronized block, and returns a reference to a partially constructed WorldCup! Needless to say, the result is neither expected nor desired.

----almost copy

转载于:https://www.cnblogs.com/jnuyao/archive/2013/02/26/2933711.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值