单例模式可以保证类的线程安全,单例模式 线程不安全
00-1010一、使用多线程时需要考虑的因素二。单一模式1。饥饿模式2。懒惰模式3。懒惰模式(同步改进)4。懒惰模式(改进了双重检查锁)三。波动性原则IV。易变的扩展(理解)
00-1010提高效率:使用多线程,充分利用CPU资源,提高任务效率。线程安全:使用多线程来确保线程安全。
所以在设计多线程代码的时候,一定要在满足线程安全的前提下,尽可能的提高任务执行的效率:细粒度的锁定:锁定的代码更少,以便并行执行其他代码。
考虑线程安全:
不操作共享变量的代码不存在安全问题。读取共享变量时,可以用volatile修改变量来写共享变量,用synchronized锁定。
00-1010 singleton模式可以保证程序中某个类只有一个实例,而不是创建多个实例。比如DataSource(数据连接池),一个数据库只需要一个连接池对象。
单例模式分为饥饿模式和懒惰模式。
00-1010饥饿中文模式是加载类时创建实例。这种模式是线程安全的(锁在JVM内部使用,即多个线程调用静态方法,只有一个线程竞争锁并完成创建,只执行一次)
实施代码:
public class Singleton { private static Singleton instance=new Singleton();私有Singleton(){ }公共静态Singleton getInstance(){ return instance;}}
00-1010惰性模式是在加载类时不创建实例,而仅在第一次使用时创建。
实施代码:
公共类Singleton {私有静态Singleton instance=nullprivate Singleton(){ } public static Singleton getInstance(){ if(instance==null){ instance=new Singleton();}返回实例;}}观察上面的代码,单线程不存在线程安全问题,但是多线程环境下存在安全问题吗?
在没有创建分析:实例时,如果多个线程调用getInstance方法,可能会创建多个实例,会出现线程安全问题。但是,一旦创建了实例,当后续线程调用getInstance方法时,就不会有线程安全问题。
结果:线程安全问题发生在第一次创建实例时。
00-1010我们使用同步装饰,代码如下:
公共类Singleton {私有静态Singleton instance=nullprivate Singleton(){ } public static synchronized Singleton getInstance(){ if(instance==null){ instance=new Singleton();}返回实例;}}线程安全的这个实现有什么问题?
解析:对方法使用同步修饰,即每次调用方法都会争用锁,但实例创建只需要做一次,即实例创建后,再次调用方法。
需要竞争锁释放锁
结果:虽然满足线程安全,但是效率低
4. 懒汉模式(使用双重校验锁改进)
在上述代码的基础上进行改动:
使用双重if判定,降低竞争锁频率使用volatile修饰instance
实现代码:
public class Singleton { private static volatile Singleton instance = null; private Singleton(){ } public static synchronized Singleton getInstance(){ if(instance == null){ //外层的if判断:如果实例被创建直接return,不让线程再继续竞争锁 //在没有创建实例时,多个线程已经进入if判断了 //一个线程竞争到锁,其他线程阻塞等待 synchronized (Singleton.class) { //内层的if判断,目的是让竞争失败的锁如果再次竞争成功的话判断实例是否被创建,创建释放锁return,没有则创建 if(instance == null){ instance = new Singleton(); } } } return instance; }}
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。