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

导读:本篇文章讲解 最最简单、功能健全,真正的单例模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、单例模式要点

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

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!