单例模式,解决线程冲突

/**
 * 单例模式的使用
 *
 * 单例创建用户服务对象 没必要给每个用户都创建一个
 *
 * 单例 :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;
}

原文地址:https://www.cnblogs.com/xrmqbl/p/4854864.html