疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java单例模式,解决线程冲突


 

   

  /**

  * 单例模式的使用

  *

  * 单例创建用户服务对象 没必要给每个用户都创建一个

  *

  * 单例 :1 构造方法私有化 2 创建一个私有的静态变量 3 公共的静态方法 当做入口

  *

  * @param user

  */

  /*

  * 第一种单例模式

  */

  // 问题 : 预先加载,没有手动实例化变量的时候 已经实例化了变量

  // 当你要使用对象的时候,只是把这个变量给你

  // 1 构造方法私有化 外界不能直接访问

  private UserService(){}

  // 2 创建一个私有的静态变量(常量)

  private static final UserService USER_SERVICE = new UserService(); // 3对外提供一个 公共的 静态的 返回该对象实例的一个方法

  public static UserService getInstance(){

  return USER_SERVICE; }

  /**

  * 第二种 问题: 排队严重 严重影响效率 因为每个用户在计算机里面都是一个单独的线程

  * 当 一个线程 调用UserService 对象以后 加了一把锁

  * 别人就访问不了了

  *

  *

  * 单例模式的目标是什么?

  * 是为了让当前类只能产生一个对象 如果 我先后创建了多个还是单例吗?.

  * @param user

  */

  private UserService(){};//构造方法私有化

  private static UserService userService = null; //先创建一个 静态变量

  public static synchronized UserService getInstance(){

  if(userService == null){ //如果为空 我返回一个新的

  userService = new UserService();

  }

  return userService; //如果不为空 直接返回

  }

  // -------------第三种---------------------

  /**

  * 如果两个线程同时判断了userService是空 进去了 第一个线程创建的疏忽,锁住了,第二个需要瞪大,第一个线程创建完了之后

  * 本来是第二个,我不需要再创建了 ,但是他已经在判断里面了,所以又创建了一个 ,所以说,单例模式没有成功

  *

  * @param user

  */

  private UserService(){}//构造方法私有化

  private static UserService userService = null;

  public static UserService getInstance() {

  if(userService == null){//如果两个或多个线程同时进入这里,判断完成后都为空,那么会创建好多对象吧,单例模式就失效了

  synchronized(UserService.class){//我现在对整个类锁了 userService = new

  UserService();

  }

  } return userService;

  }

  // -----------------第四种----------------

  private UserService() {

  }// 构造方法私有化

  private static UserService userService = null;// 私有的静态变量

  public static UserService getInstance() {// 获取当前类对象的方法

  if (userService == null) {

  synchronized (UserService.class) {// 现在是对整个类锁住了

  if (userService == null) {// 更上面第三章方法一样,当前就能解决第三种方法的问题(创建了多个对象),因为,就是两个同事进入上面的if判断,到这里,就会判断不通过,就会直接返回一个对象,不会在去创建新的对象

  userService = new UserService();

  }

  }

  }

  return userService;

  }