最最简单、功能健全,真正的单例模式

一、单例模式要点

1、某个只能有一个对象
2、必须自行创建这个实例
3、必须向整个系统提供这个实例
4、基于多线程也适用

二、实现步骤(详细)

1、创建一个简单的构造函数

代码如下(创建一个构造函数):

public class SingleInstance {
	

	public SingleInstance() {
		System.out.println("我是一个构造函数");
	}
	
}

代码如下(测试):

public class Test01 {

	public static void main(String[] args) {
		SingleInstance singleInstance1 = new SingleInstance();

	}

}

代码如下(运行结果):

我是一个构造函数片

2、构造函数私有化

代码如下(改变构造函数的修饰词):

public class SingleInstance {
	

	private SingleInstance() {
		System.out.println("我是一个构造函数");
	}
	
}

代码如下(测试是报错的):

public class Test01 {

	public static void main(String[] args) {
		SingleInstance singleInstance1 = new SingleInstance();

	}

}

小结

由private修饰的构造函数在测试中是不能初始化的,所以只能再想办法

3、通过一个公有的方法提供访问

public class SingleInstance {

	private SingleInstance() {
		System.out.println("我是一个构造函数");
	}
	public  static SingleInstance getSingleInstance() {
		return singleInstance;
		
	}
}

小结

由于构造函数是由private修饰的所以只能采取提供方法来访问,目前优先想到的是由static一起修饰的方法,访问格式是:类名.方法名 但是static修饰有自己的局限性,所以想要达到预期效果同步效果,成员变量也得是static来修饰,否则方法加载成功但是成员变量还没有加载,就会出现报错。

4、创建一个成员变量

public class SingleInstance {
	private  static SingleInstance singleInstance=new SingleInstance();

	private SingleInstance() {
		System.out.println("我是一个构造函数");
	}
	public  static SingleInstance getSingleInstance() {
		return singleInstance;
		
	}
}

5、为了适应在多线程场景在singleInstance 处加上final修饰

public class SingleInstance {
	private static final SingleInstance singleInstance = new SingleInstance();
	private SingleInstance() {
		System.out.println("我是一个构造函数");
	}
	public  static SingleInstance getSingleInstance() {
		return singleInstance;
		
	}
}

代码如下(测试):

public class Test01 {

	public static void main(String[] args) {
		SingleInstance singleInstance = SingleInstance.getSingleInstance();
		System.out.println(singleInstance);
		SingleInstance singleInstance1 = SingleInstance.getSingleInstance();
		System.out.println(singleInstance1);

	}

}

小结

在这之后要在加一个锁的存在,因为如不加锁在多线程场景中,线程的访问时随机的,可能会有一个或多个线程进入到提供访问的公有方法中,那么单例模式就不存在,在最后我们总算得到了自己想要看到的结果,但是还是有不足那就是static修饰的通病就是如果加载进去用不到那就是占资源,所以为了解决这一毛病,我们可以在成员变量直接将初始化赋予null ,在提供访问的方法这里进行一个判断如果需要访问了就会进行判断,开始进行初始化,不需要则就不初始化,占资源的问题就迎刃而解了!!!

5、简单单例函数优化(懒汉式)

代码如下(优化):

public class SingleInstance {
	private  static SingleInstance singleInstance=null;

	private SingleInstance() {
		System.out.println("我是一个构造函数");
	}
	public  static synchronized SingleInstance getSingleInstance() {
		if(singleInstance == null) {
			singleInstance = new SingleInstance();
		}
		return singleInstance;
		
	}
}

代码如下(测试):

public class Test01 {

	public static void main(String[] args) {
		SingleInstance singleInstance1 = SingleInstance.getSingleInstance();
		System.out.println(singleInstance1);
		SingleInstance singleInstance2 = SingleInstance.getSingleInstance();
		System.out.println(singleInstance2);
		SingleInstance singleInstance3 = SingleInstance.getSingleInstance();
		System.out.println(singleInstance3);

	}

}

代码如下(测试结果):

我是一个构造函数
com.etime03.SingleInstance@70dea4e
com.etime03.SingleInstance@70dea4e
com.etime03.SingleInstance@70dea4e

6、简单单例函数(饥汉式)

其实就是在懒汉式的成员变量哪里改了一下再加一个final修饰,判断不需要了,其他的都一样的。

public class SingleInstance {
	private  static final SingleInstance singleInstance=new SingleInstance();

	private SingleInstance() {
		System.out.println("我是一个构造函数");
	}
	public  static SingleInstance getSingleInstance() {
		return singleInstance;
		
	}
}

三、总结

以前写的单例模式由于没有学到多线程,所以是拙劣的,目前学到了多线程就知道,还有一个多线程场景需要考虑到,特来加上一个同步函数的公有访问方法以备完善。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值