文章目录
一、单例模式要点
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、为了适应在多线程场景在提供访问的方法中加入synchronized
public class SingleInstance {
private static final SingleInstance SingleInstance = null;
private SingleInstance() {
System.out.println("我是一个构造函数");
}
public static synchronized 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;
}
}
三、总结
以前写的单例模式由于没有学到多线程,所以是拙劣的,目前学到了多线程就知道,还有一个多线程场景需要考虑到,特来加上一个同步函数的公有访问方法以备完善。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/5103.html