<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    dingfirst

    On the Road

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      8 隨筆 :: 2 文章 :: 3 評論 :: 0 Trackbacks

    原文名稱:Double-checked locking and the Singleton pattern

    ???????????????????????????A comprehensive look at this broken programming idiom


    1,請首先看一下下面的這個類,只有第一個getInstance()方法是正確的。其中getInstance4()就是由于所謂的"out-of-order"問題引起的(詳見注釋),而
    getInstance5()則是因為編譯器優化導致的。

    package ?org.ding.util;
    import ?java.util. * ;

    public ? class ?Singleton? {
    ????
    ????
    private ? static ?Singleton?instance;
    ????
    private ?Vector?v;
    ????
    private ? boolean ?inUse;


    ????
    private ?Singleton()? {
    ????????v?
    = ? new ?Vector();
    ????????v.addElement(
    new ?Object());
    ????????inUse?
    = ? true ;
    ????}

    ????
    ????
    // ok
    ???? public ? static ? synchronized ?Singleton?getInstance()? {
    ????????
    if ?(instance? == ? null )? // 1
    ????????????instance? = ? new ?Singleton();? // 2
    ???????? return ?instance;? // 3
    ????}


    ????
    ????
    // error
    ???? public ? static ?Singleton?getInstance2()? {
    ????????
    if ?(instance? == ? null )? // 1
    ????????????instance? = ? new ?Singleton();? // 2?,此處競爭
    ???????? return ?instance;? // 3
    ????}

    ????
    ????
    // error
    ???? public ? static ?Singleton?getInstance3()? {
    ????????
    if ?(instance? == ? null )? {
    ????????????
    synchronized ?(Singleton. class )? {?? // 此處競爭
    ????????????????instance? = ? new ?Singleton();
    ????????????}

    ????????}

    ????????
    return ?instance;
    ????}


    ????
    /*
    ?????*error
    ?????*known?as?double-checke
    ?????*
    ?????*The?issue?of?the?failure?of?double-checked?locking?is?not?due?to?implementation?bugs?in?JVMs?
    ?????*but?to?the?current?Java?platform?memory?model.?
    ?????*The?memory?model?allows?what?is?known?as?"out-of-order?writes"?and?is?a?prime?reason?why?this?idiom?fails.
    ?????*
    ?????*看一下代碼的//3處是如何執行的:
    ?????*???????mem?=?allocate();?????????????//a,Allocate?memory?for?Singleton?object.
    ?????*???????instance?=?mem;???????????????//b,Note?that?instance?is?now?non-null,?but?has?not?been?initialized.
    ?????*???????ctorSingleton(instance);??????//c,Invoke?constructor?for?Singleton?passing?instance.
    ????
    */

    ????
    public ? static ?Singleton?getInstance4()? {
    ????????
    if ?(instance? == ? null )? {? // 1
    ???????????? synchronized ?(Singleton. class )? {? // 2
    ???????????????? if ?(instance? == ? null )? // 3
    ????????????????????instance? = ? new ?Singleton();? // 3,此處線1程如果執行完b,但還沒有執行c的時候,線程2執行 // 1,會返回未完全初始化的對象
    ????????????}

    ????????}

    ????????
    return ?instance;
    ????}

    ????
    ????
    // error
    ????
    // 這個的問題在于:
    ????
    // The?Java?Language?Specification?(JLS)?demands?that?code?within?a?synchronized?block?not?be?moved?out?of?a?synchronized?block.?
    ????
    // However,?it?does?not?say?that?code?not?in?a?synchronized?block?cannot?be?moved?into?a?synchronized?block.

    ????
    /**
    ?????*?getInstance5??error
    ?????*
    ?????*?這個方法失敗的問題在于:
    ?????*?The?Java?Language?Specification?(JLS)?demands?that?code?within?a?synchronized?block?not?be?moved?out?of?a?synchronized?block.?
    ?????*?However,?it?does?not?say?that?code?not?in?a?synchronized?block?cannot?be?moved?into?a?synchronized?block.
    ?????*?
    ?????*?所以//3至//5之間的代碼會被編譯器優化為:
    ?????*???????if?(inst?==?null)?{
    ?????*????????????synchronized?(Singleton.class)?{?//3
    ?????*???????????????instance?=?new?Singleton();???????????????
    ?????*?????????????}
    ?????*????????}
    ?????*
    ?????*?
    @return ?Singleton
    ?????
    */

    ????
    public ? static ?Singleton?getInstance5()? {
    ????????
    if ?(instance? == ? null )? {
    ????????????
    synchronized ?(Singleton. class )? {? // 1
    ????????????????Singleton?inst? = ?instance;? // 2
    ???????????????? if ?(inst? == ? null )? {
    ????????????????????
    synchronized ?(Singleton. class )? {? // 3
    ????????????????????????inst? = ? new ?Singleton();? // 4
    ????????????????????}

    ????????????????????instance?
    = ?inst;? // 5
    ????????????????}

    ????????????}

    ????????}

    ????????
    return ?instance;
    ????}

    }

    2,還有一種正確的方式
    class?Singleton2?{
    ????
    private?Vector?v;
    ????
    private?boolean?inUse;
    ????
    private?static?Singleton2?instance?=?new?Singleton2();

    ????
    private?Singleton2()?{
    ????????v?
    =?new?Vector();
    ????????inUse?
    =?true;
    ????????
    //
    ????}


    ????
    public?static?Singleton2?getInstance()?{
    ????????
    return?instance;
    ????}

    }

    3,volitile為什么不行?

    Another idea is to use the keyword volatile for the variables inst and instance. According to the JLS (see Resources), variables declared volatile are supposed to be sequentially consistent, and therefore, not reordered. But two problems occur with trying to use volatile to fix the problem with double-checked locking:

    • The problem here is not with sequential consistency. Code is being moved, not reordered.

    • Many JVMs do not implement volatile correctly regarding sequential consistency anyway.

    The second point is worth expanding upon. Consider the code in Listing 9:


    Listing 9. Sequential consistency with volatile
    class test
    {
      private volatile boolean stop = false;
      private volatile int num = 0;
    
      public void foo()
      {
        num = 100;    //This can happen second
        stop = true;  //This can happen first
        //...
      }
    
      public void bar()
      {
        if (stop)
          num += num;  //num can == 0!
      }
      //...
    }
    

    According to the JLS, because stop and num are declared volatile, they should be sequentially consistent. This means that if stop is ever true, num must have been set to 100. However, because many JVMs do not implement the sequential consistency feature of volatile, you cannot count on this behavior. Therefore, if thread 1 called foo and thread 2 called bar concurrently, thread 1 might set stop to true before num is set to 100. This could lead thread 2 to see stop as true, but num still set to 0. There are additional problems with volatile and the atomicity of 64-bit variables, but this is beyond the scope of this article. See Resources for more information on this topic.

    4,String類會有"out-of-order"問題么?

    ???答案是比較老的版本會有:
    ???"Running this code on old JVMs like Sun JDK 1.2.1 results in the out-of-order write problem, and thus, a non-immutable String."
    ???"Both the IBM 1.3 and Sun 1.3 JVMs produce immutable Strings as expected."

    class?StringReader?extends?Thread?{
    ????MutableString?ms;
    ????
    public?StringReader(MutableString?muts)?{
    ????????ms?
    =?muts;
    ????}


    ????
    public?void?run()?{
    ????????
    while?(true)?{
    ????????????
    if?(!(ms.str.equals("hello")))?{?//2
    ????????????????System.out.println("String?is?not?immutable!");//Peter Haggar?說此處是由輸出的。
    ????????????????
    break;
    ????????????}

    ????????}

    ????}

    }


    class?MutableString?{
    ????
    public?String?str;?//3
    ????public?static?void?main(String?args[])?{
    ????????MutableString?ms?
    =?new?MutableString();?//4
    ????????new?StringCreator(ms).start();?//5
    ????????new?StringReader(ms).start();?//6
    ????}

    }
    posted on 2006-07-18 19:17 dingfirst 閱讀(332) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 最近的免费中文字幕视频 | 久久精品国产亚洲AV| 国产AV无码专区亚洲AV琪琪| 免费人成在线观看视频高潮| 日本zzzzwww大片免费| 亚洲美女高清一区二区三区| 亚洲电影唐人社一区二区| 一级特黄录像免费播放中文版| 无码精品A∨在线观看免费| 亚洲精品一级无码中文字幕| 免费的黄色网页在线免费观看| 91制片厂制作传媒免费版樱花| 亚洲欧洲国产成人综合在线观看| 一级做a爱过程免费视| 亚洲日韩精品无码一区二区三区 | 亚洲熟妇AV一区二区三区浪潮 | 成人AV免费网址在线观看| 亚洲成av人影院| 日韩免费码中文在线观看| 免费91最新地址永久入口| 免费一级毛片在线播放不收费| 亚洲人成小说网站色| 色老头永久免费网站| 麻豆狠色伊人亚洲综合网站| 69视频免费在线观看| 亚洲 日韩 色 图网站| 免费午夜爽爽爽WWW视频十八禁| 国产又黄又爽又大的免费视频 | 成人免费淫片在线费观看| 老司机免费午夜精品视频| 国产男女猛烈无遮挡免费网站| 亚洲综合精品一二三区在线| 国产一级黄片儿免费看| 亚洲精品中文字幕无乱码| 精品少妇人妻AV免费久久洗澡| 亚洲高清视频免费| 99在线免费观看视频| 亚洲欧洲日韩国产综合在线二区| 国产午夜精品免费一区二区三区| 亚洲一区二区三区久久| 国产情侣激情在线视频免费看 |