单例设计模式分析
什么是单例设计模式?
单例模式是什么,看名字就应该可以猜到就是单个实例化,就是在一个应用程序中某些类只有一次实例化。
为什么要使用单例模式?
因为在一个应用程序中你某个类实例化对象次数过多可能导致某个地方拿到该类的数据是错的,而另一方面是因为实例化的次数过多照成的内存空间也比较浪费,大家都知道每次new都会创建一个内存空间。所以我们可以使用单例模式来避免。接下来给大家看一个例子.
class Test{
public int age = 1;
}
public class AlexaServer {
public static void main(String[] args) {
Test test1 = new Test();
test1.age = 2;
Test test2 = new Test();
System.out.println(test2.age); //输出结果为1
}
}
在给大家一张类图看
因为每次new都会创建一个新的空间然后里面的数据都是初始的。
单例模式的设计思想
- 不在其他程序用new:因为每次new一个对象就会创建一个内存空间,而每个对象对应不同的内存空间所有获取的数据是不一样的,还会照成资源浪费。
- new对象:因为不允许其他应用new对象,所以只能在本类中new对象
- 提供一个开发的获取对象的方法:因为你在本类中new对象,其他应用获取不到,所以这时候要提供一个公开的获取对象的方法
单例模式的实现方式
接下来就是写代码,单例模式有很多种实现方式,请看下面的例子
懒汉式(线程不安全)
- 这种方式不支持多线程模式,因为没用加锁synchronized,当多个线程同时进入会实例化多个对象
- 对于单线程来说很有效率,因为是在调用的时候实例化也不会照成资源浪费
class Singleton{
private static Singleton singleton;
private Singleton(){}
public static Singleton getSingleton(){
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
懒汉式(线程安全)
- 就是加上synchronized给方法加上锁
- 因为加锁的原因其效率会下降,因为每次进入一个线程,其他线程则会等待。
class Singleton{
private static Singleton singleton;
private Singleton(){}
public static synchronized Singleton getSingleton(){
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
饿汉式
- 在本类直接new一个实例化对象,因为是被final修饰的所以不能更改
- 没有加锁,效率高
- 由于是在程序启动的时候实例化会照成资源浪费
class Singleton{
private static final Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getSingleton(){
return singleton;
}
}
双重检验锁模式(多线程)
- 同步块外的检索是为了避免线程等待
- 同步块内的检索是为了防止又多个线程进入到同步块里面然后实例化多个对象
class Singleton{
private static volatile Singleton singleton = null;
private Singleton(){}
public static Singleton getSingleton(){
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
静态内部类式
- 延迟加载,避免在类被加载的时候实例化对象,所以放到静态内部类里面
- 线程安全,因为静态内部类只会加载一次
public class Singleton {
private static class SingletonHolder{
private static final Singleton SINGLETON = new Singleton();
}
private Singleton(){
}
public static final Singleton getSingleton(){
return SingletonHolder.SINGLETON;
}
}
枚举模式
一种新的单例模式,在工作中基本不怎么用(我也不怎么用)
感觉挺方便的,而且在网上看到可以避免多个线程同时实例化对象,线程安全
public enum Test{
TEST;
public void show(){
}
}
多例设计模式分析
单例模式就是指一个实例,那么多例就是指多个实例
例子:
class Test2 {
//构造方法私有化
private Test2(String title) {
this.title=title;
}
//实例化对象
private static final Test2 MALE=new Test2("男");
private static final Test2 FEMALE=new Test2("女");
//属性私有化
private String title;
//取得外部对象的方法
public static Test2 getInstance(String msg) {
switch(msg) {
case "male":
return MALE;
case "female":
return FEMALE;
default:
return null;
}
}
//getter方法
public String getTitile() {
return title;
}
}
class Test{
public static void main(String[] args) {
Test2 t2=Test2.getInstance("male");
System.out.println(t2.getTitile());
}
}