简述建设电子商务网站步骤写软文怎么接单子
news/
2025/9/22 16:28:51/
文章来源:
简述建设电子商务网站步骤,写软文怎么接单子,网站建设所用软件,seo优化排名是什么目录
今日良言#xff1a;关关难过关关过#xff0c;步步难行步步行
一、单例模式
1.饿汉模式
2.懒汉模式
二、工厂模式 今日良言#xff1a;关关难过关关过#xff0c;步步难行步步行 一、单例模式
首先来解释一下#xff0c;什么是单例模式。
单例模式也就是单个…目录
今日良言关关难过关关过步步难行步步行
一、单例模式
1.饿汉模式
2.懒汉模式
二、工厂模式 今日良言关关难过关关过步步难行步步行 一、单例模式
首先来解释一下什么是单例模式。
单例模式也就是单个实例(对象)。在有些场景中只能创建出一个实例不应该创建多个实例。
单例模式就是针对上述的需求场景进行了个更强制的保证通过巧用 java 现有的语法达成了某个类 只能被创建出一个实例这样的效果.(当程序猿不小心创建了多个实例就会编译报错)。
单例模式最常见的两种就是饿汉模式和懒汉模式。
1.饿汉模式
代码如下:
class Singleton{// 在此处就把实例给创建出来了private static Singleton instance new Singleton();// 如果需要使用这个唯一的实例统一通过这个方法获取public static Singleton getInstance() {return instance;}// 为了避免Singleton 类不小心被赋值出多份将构造方法设置成private.// 此时就无法通过new 的方式来创建这个Singleton 实例了。private Singleton(){}
}
public class Exercise {public static void main(String[] args) {Singleton s1 Singleton.getInstance();Singleton s2 Singleton.getInstance();System.out.println(s1 s2);}
} 在类加载阶段就将实例创建好了这种效果就给人一种“特别急切”的感觉。
被static修饰表示这个属性和实例无关而是和类相关。
Java 代码中的每个类都会在编译完成后得到.class 文件JVM 运行时就会加载这个.class文件读取其中的二进制指令并且在内存中构造出对应过的类对象(形如Singleton.class)具体的类加载可以阅读博主之前写的博客
深度剖析JVM三个面试常考知识点_程序猿小马的博客-CSDN博客
由于 类对象在一个 Java 进程中是唯一的因此这个类对象的内部的类属性也是唯一的。 static 在这里的作用有两个 1static 保证这个实例唯一。 2static 保证这个实例确实在一定的时机被创建出来。 static 属于这个实现方式中的灵魂角色。 2.懒汉模式
代码实现:
class SingletonLazy {private static SingletonLazy instance null;public static SingletonLazy getInstance() {if (instance null) {instance new SingletonLazy();}return instance;}// 构造方法设置成私有的private SingletonLazy(){}
}
public class Exercise {public static void main(String[] args) {SingletonLazy s1 SingletonLazy.getInstance();SingletonLazy s2 SingletonLazy.getInstance();System.out.println(s1 s2);}
} 这个实例并非是类加载阶段创建而是真正第一次使用的时候才去创建 如果不用就不创建了。 上述写的饿汉模式和懒汉模式是在单线程情况下的代码如果在多线程下调用getInstance 是否是线程安全的呢?
答案是一个是线程安全的一个是线程不安全的。
饿汉模式是线程安全的因为饿汉模式的 getInstance 方法只涉及到“读操作”。
懒汉模式是线程不安全的因为懒汉模式的 getInstance 方法既有读操作又有写操作。
线程安全问题的详细解释博主在之前的博客中有提到
线程安全问题_程序猿小马的博客-CSDN博客
这里如果在多线程情况下调用懒汉模式的 getInstance 方法会发生多次 new 操作显然就不是单例了。
那么如何让上述懒汉模式能够成为线程安全的呢
加锁
上述线程安全问题本质上是 修改操作不是原子的因此需要保证这个修改操作是原子的。
修改代码如下: 此时把锁加到外面保证了读操作和修改操作是一个整体。
但是代码写到这里还有问题上述这种写法就导致了每次 getInstance 都需要加锁加锁操作都是有开销的仔细考虑一下这里真的需要每次都加锁吗
显然不是这里的加锁只是在new出对象之前加上是有必要的一旦对象 new 完以后后续调用 getInstance 此时 instance 一定是非空的因此会直接 return。
基于上述讨论就可以给刚才的代码加上一个判定
如果对象还没创建才加锁如果对象已经创建过了就不加锁了。
修改代码如下: 此时这里就不再是无脑加锁了而是满足了特定条件之后才真正加锁。 注意 这两个if 的作用不一样第一个if 判断是否要加锁第二个if 判断是否要创建对象。 加锁操作可能会引起线程阻塞当执行到锁结束之后执行到第二个 if 的时候第二个 if 和第一个 if 之间可能已经隔了很久的时间了instance 变量可能已经被别的线程给修改过了所以需要第二次 if 判断当前线程是否需要创建对象。 上述代码其实还存在问题: 内存可见性问题以及指令重排序
关于这个问题博主之前的博客也有详细介绍
线程安全问题_程序猿小马的博客-CSDN博客 内存可见性问题
假设有很多线程都去进行 getInstance 这个时候可能会存在被优化的风险(只有第一次读的时候才真正的读了内存后续都是读寄存器)
指令重排序
instance new SingletonLazy();
这个操作可以拆分为三个步骤
1申请内存空间。
2调用构造方法把这个内存空间初始化成一个合理的对象。
3把内存空间的地址赋值给 instance 引用。
正常情况下是按照 1 2 3 这个顺序执行代码但是编译器存在指令重排序问题编译器为了提高程序效率会调整代码执行顺序 1 2 3 可能就变成了 1 3 2 如果是单线程下1 2 3 和 1 3 2 没有本质区别但是多线程下就会出现问题了。
假设线程 t1 是 按照 1 3 2 的步骤执行的t1 执行到 1 3 之后执行 2 之前被切除 cpu 此时 t2执行当 t1 执行完 3 之后t2 看起来此处的引用就非空了此时此刻t2 就相当于直接返回了 instance 引用并且可能会尝试使用引用中的属性但是由于 t1 中的 2 操作还没执行完呢t2 拿到的是非法的对象还没构造完成的不完整的对象。
因此需要解决上述问题使用 volatile
修改代码如下 懒汉模式完整代码如下:
class SingletonLazy {private volatile static SingletonLazy instance null;public static SingletonLazy getInstance() {if (instance null) {synchronized (SingletonLazy.class) {if (instance null) {instance new SingletonLazy();}}}return instance;}// 构造方法设置成私有的private SingletonLazy(){}
}
public class Exercise {public static void main(String[] args) {SingletonLazy s1 SingletonLazy.getInstance();SingletonLazy s2 SingletonLazy.getInstance();System.out.println(s1 s2);}
}
二、工厂模式
先来解释一下什么是工厂模式。
工程模式用一句话概括使用普通的方法来代替构造方法创建对象。
为什么要代替呢 这是因为构造方法有坑坑就体现在如果只构造一种对象好办如果要构造多种不同的情况就不好办了。
举个例子
假设现在有一个类表示平面上的一个点 上述构造方法表示使用笛卡尔坐标系提供的坐标来构造点。
如果这里假设再使用极坐标来构造点代码如下
很明显这个代码存在问题正常来说多个构造方法是通过“重载”的方式来提供的重载要求的是 方法名相同参数的个数或者类型不同。 为了解决这个问题就可以使用工厂模式 普通方法的方法名没有限制因此有多种方式构造使用不同的方法名即可。
以上就是单例模式和工厂模式的介绍。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909636.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!