1.Java 面试之单子模式
单子模式要满足以下几点
1, 构造函数私有化,使得不能通过new来实例化对象
2,通过new在类的内部创建唯一的实例化对象
3,定义一个公有的静态的方法来返回上一部的对象
单子模式分为懒汉模式和饿汉模式
饿汉模式*
以下通过代码来讲解什么饿汉模式
public class Single {//1 私有构造器。外部不能访问private Single(){}//2 声明一个静态的自己的类private static Single single = new Single();//3 返回一个返回自己类的方法public static Single getInstance(){return single;}}
测试类:打出实例化之后的对象地址
public class Test {public static void main(String[] args) {Single single1 = Single.getInstance();Single single2 = Single.getInstance();System.out.println(single1);System.out.println(single2);}}
运行结果
:Test.main()csdn.Single@15db9742csdn.Single@15db9742
发现地址都一样,说明实例化的是一个对象
特点是不管对象有没有为空,直接实例化
懒汉模式
public class Single2 {private Single2(){}private static Single2 single2;public static Single2 getInstance(){if(single2==null){single2 = new Single2();}return single2;}}
public class Test {public static void main(String[] args) {Single2 single1 = Single2.getInstance();Single2 single2 = Single2.getInstance();System.out.println(single1);System.out.println(single2);}}
运行结果:
:Test.main()csdn.Single2@15db9742csdn.Single2@15db9742
可以看出地址是一样的,懒汉模式一旦第一次实例化成功后,这个对象就不动了,因为是static
还有就是因为要判断一次对象是否为空,这也是他和饿汉的区别,他相比较,实例化比较温柔
但是由于在多线程操作下,对象判空这一项会受到多线程的影响,可能线程a进行了实例化但是线程b同时进行判空就会发生错误,所以就要对实例化判断进行同步锁的注入
代码:
public class Single3 {private static Single3 single3;private Single3(){}public static Single3 getInstance(){synchronized (Single3.class){if(single3==null){single3 = new Single3();}}return single3;}}
这样就解决了多线程并发的错误
但还是缺点:每次调用方法时都要加锁,而加锁很耗时,所以在保证对象为null时只new出一个实例时加锁就够了
改进如下:
public class Single4 { private static Single4 single4;private Single4(){}public static Single4 getInstance(){if(single4==null){synchronized (Single4.class){if(single4==null){single4 = new Single4();}}}return single4;}}
静态代码块
在静态代码块中加入对该自身对象的实例化,因为JDK会在静态代码区中对其代码仅执行一次
public class Single5 {private Single5(){}private static Single5 single5;static{//本身就是线程同步且仅执行一次single5 = new Single5();}//这里不需要加锁,因为他会在jdk区进行单线程的实例化public static Single5 getInstance(){return single5;}}
结果:
:Test.main()csdn.Single5@15db9742csdn.Single5@15db9742
静态代码按需创建(静态内部类)
如果按上面的方法,在执行静态方法后会对程序产生影响,为了避免这个问题,改进一个内部类的手段进行优化:
public class Single6 {private Single6(){}//建立内部类private static class Nested{private static Single6 single6;static{single6 = new Single6();}}public static Single6 getInstance(){return Nested.single6;}}
以上就是所有的单子模式,欢迎补充
如果觉得《Java 面试之单子模式》对你有帮助,请点赞、收藏,并留下你的观点哦!