package com.jan;
/***
* 手写单例模式
*
*懒汉模式
* 饿汉模式
* 双重检查锁单例
*/
//懒汉模式
public class SingleTon {
private static SingleTon single;
public SingleTon() {
}
/***
* 缺陷: 线程不安全,如果两个线程同时访问到了getSingleTon()方法,
* 并且都走到了“single == null”这个判断时,此时single实例未被创建,
* 所以两个线程都会创建一个实例
*/
public static SingleTon getSingleTon() {
if(single==null){
single = new SingleTon();
}
return single;
}
/***
* 改进:
* 优点: 第一次调用才初始化,避免内存浪费
* 缺点: 必须加锁 synchronized 才能保证单例,但加锁会影响效率
* @return
*/
public static synchronized SingleTon getSingle1(){
if(single==null){
single = new SingleTon();
}
return single;
}
}
//饿汉模式
/***
* 饿汉式更为安全,在类加载的时候就已经自行创建了实例,
* getSingle2方法里面一直引用的就是这个实例,而且永远不会释放,一直存在内存中,知道程序结束
*/
class SingleTon2 {
private static SingleTon2 single2 = new SingleTon2();
public SingleTon2() {
}
public static synchronized SingleTon2 getSingle2(){
return single2;
}
}
//双重检查
/***
* 其中用了两个if 判断,第一个if 先判断singleton是否为null,
* 如果不为null,说明singleton 已经被初始化了,直接返回singleton
* 避免了多个线程同时获取synchronized 锁;
* 如果singleton 为null ,说明singleton 还没有被初始化,
* 这样才会去执行synchronized 修饰的代码块内容,只在其初始化的时候调用一次。
* 这样的设计既能保证只产生一个实例,并且只在初始化的时候加同步锁,也实现了延迟加载。
*/
class SingleTon3 {
// volatile可以实现多线程的可见性 有序性 但是不保证一致性
private static volatile SingleTon3 single3;
public SingleTon3() {
}
public static SingleTon3 getSingle3(){
// 最外层if 过滤掉不为null 的线程 提高效率
if(single3==null){
synchronized (SingleTon3.class){
if(single3==null){
single3 = new SingleTon3();
}
}
}
return single3;
}
}
手写单例模式
最新推荐文章于 2024-09-27 00:45:01 发布
这篇博客深入探讨了Java中的三种单例模式实现:懒汉模式、饿汉模式和双重检查锁单例。懒汉模式在多线程环境中存在线程安全问题,可以通过同步方法解决,但会降低效率。饿汉模式在类加载时即创建实例,保证线程安全但可能导致内存浪费。双重检查锁单例则在保证线程安全的同时实现了延迟加载,提高了效率。
摘要由CSDN通过智能技术生成