科技
当前位置:首页 > 科技>正文

java设计模式(原创)

字号+作者:methon 来源:今日看点www.hatdot.com 2020-08-26 00:15

1.界说确保一个类只有一个实例,并提供一个全局会见点。2.实现方式2.1 声明即建立工具方式package com.methon.singleton;pub'...

1.界说

确保一个类只有一个实例,并提供一个全局会见点。

2.实现方式

2.1 声明即建立工具方式

package com.methon.singleton;public class SigDemo01 {    private static SigDemo01 INSTANCE=new SigDemo01 ();    private SigDemo01 (){};    public static SigDemo01 getInstance(){        return INSTANCE;    }    public static void main(String[] args) {        SigDemo01 sig01=SigDemo01 .getInstance();        SigDemo01 sig02=SigDemo01 .getInstance();        /* 判断是否是同一个工具 */        System.out.println(sig01==sig02);    }}

其中static声明的静态成员INSTANCE只会在类加载的时候建立一次,new一个工具。
私有的结构函数保证只能在此类中挪用,其他类中想要获取实例只能挪用getInstance()方法。
返回static工具。保证工具的唯一性。上面的代码也可以写成:

package com.methon.singleton;public class SigDemo02{    private static SigDemo02 INSTANCE;    static {        INSTANCE=new SigDemo02();    }    private SigDemo02(){};    public static  SigDemo02 getInstance(){        return INSTANCE;    }    public static void main(String[] args) {        SigDemo02 sig01=SigDemo02.getInstance();        SigDemo02 sig02=SigDemo02.getInstance();        /* 判断是否是同一个工具 */        System.out.println(sig01==sig02);    }}

2.2 懒加载方式

以下为懒加载方式的演变,方法逐渐变得趋于完美

2.2.1 错误的懒加载写法(不支持多线程)

package com.methon.singleton;public class SigDemo03{    private static SigDemo03 INSTANCE;    private SigDemo03(){    }    public static SigDemo03 getInstance(){        if(INSTANCE==null){            INSTANCE=new SigDemo03();        }        return INSTANCE;    }    public static void main(String[] args) {        for (int i = 0; i < 100; i++) {            new Thread(()-> System.out.println(SigDemo03.getInstance().hashCode())).start();        }    }}

如果代码中没有多线程,则法式没有任何问题。但存在多线程的情况下,执行到if(INSTANCE==null)后, INSTANCE=new SigDemo03()语句前,可能有多个线程通过了if(INSTANCE==null)的判断,从而不能保证建立出的工具有且仅有1个。

2.2.2 懒加载的正确写法(加锁)

package com.methon.singleton;public class SigDemo04{    private static SigDemo04 INSTANCE;    private SigDemo04() {    }    public static synchronized SigDemo04 getInstance() {        if (INSTANCE == null) {            INSTANCE = new SigDemo04();        }        return INSTANCE;    }    public static void main(String[] args) {        for (int i = 0; i < 100; i++) {            new Thread(() -> System.out.println(SigDemo04.getInstance().hashCode())).start();        }    }}

对比之前的方法,只是在getInstance()方法上添加了synchronized ,保证了线程宁静。但这样做的话降低了法式的执行效率。

2.2.3 为相识决加锁后法式效率变低而接纳的错误处置惩罚

package com.methon.singleton;public class SigDemo05{    private static SigDemo05 INSTANCE;    private SigDemo05() {    }    public static SigDemo05 getInstance() {        if (INSTANCE == null) {            synchronized (SigDemo05.class) {                 INSTANCE = new SigDemo05 ();            }                  }        return INSTANCE;    }    public static void main(String[] args) {        for (int i = 0; i < 100; i++) {            new Thread(() -> System.out.println(SigDemo05 .getInstance().hashCode())).start();        }    }}

为了提高效率,在判断INSTANCE == null之后在举行加锁的判断。可是请注意,虽然举行了加锁操作,可是最后线程们都市建立新的工具。

2.2.4 为相识决加锁后法式效率变低而接纳的正确处置惩罚

package com.methon.singleton;public class SigDemo06{    private static SigDemo06 INSTANCE;    private SigDemo06 () {    }    public static SigDemo06 getInstance() {        if (INSTANCE == null) {            synchronized (SigDemo06 .class) {                if (INSTANCE == null) {                    INSTANCE = new SigDemo06 ();                }            }        }        return INSTANCE;    }    public static void main(String[] args) {        for (int i = 0; i < 100; i++) {            new Thread(() -> System.out.println(SigDemo06 .getInstance().hashCode())).start();        }    }}

此方式虽然有些繁琐,可是正确的做法。在判断INSTANCE == null后举行加锁,之后在举行判空操作。仍为空后在举行new新的工具。制止了只要为空就会建立新的工具。

2.2.5 较完美的静态内部类方式

package com.methon.singleton;public class SigDemo07{    private SigDemo07() {    }    public static SigDemo07 getInstance() {        return SigDemo07Holder.INSTANCE;    }    private static class SigDemo07Holder {        private final static SigDemo07 INSTANCE = new SigDemo07();    }    public static void main(String[] args) {        for (int i = 0; i < 100; i++) {            new Thread(() -> System.out.println(SigDemo07.getInstance().hashCode())).start();        }    }}

此种方式,制止了声明即建立工具的方式,接纳静态内部类的方式,需要时才建立工具。比力完美且代码不冗余。

2.2.6 effictive java给出的方式

package com.methon.singleton;public enum  SigDemo08{    INSTANCE;    public static void main(String[] args) {        for (int i = 0; i < 100; i++) {            new Thread(() -> System.out.println(SigDemo08.INSTANCE.hashCode())).start();        }    }}

直接设置成了枚举类型,且仅有一个枚举量INSTANCE。

3.总结

正常需要单例模式的情况一般都需要建立工具。所以是否举行懒加载区别相差不大。故方法2.1满足平常使用的要求。除此之外,方法2.2.4, 2.2.5, 2.2.6更为完美,推荐使用。

1.【今日看点】遵循行业规范,任何转载的稿件都会明确标注作者和来源;2,今日看点的原创文章,请转载时务必注明文章作者和"来源:今日看点",不尊重原创的行为【今日看点】或将追究责任;3.作者投稿可能会经今日看点编辑修改或补充。

排行榜