单例模式可以保证类的线程安全,单例模式 线程不安全

  单例模式可以保证类的线程安全,单例模式 线程不安全

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: