设计模式----单例模式(JAVA)

单例模式

/**
 * 单例模式
 * 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
 * 解决的问题:一个全局使用的类频繁地创建与销毁。
 * 分类:
 * 懒汉模式:线程不安全,延迟初始化,严格意义上不是不是单例模式
 * 饿汉模式:线程安全,比较常用,但容易产生垃圾,因为一开始就初始化
 * 双重线程锁模式:线程安全,延迟初始化。这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
 * 优点:、
 * 因为是全局唯一的,所以减少了类的创建与销毁时候的开销。
 * 对于一些资源的实例,可以更加容易进行管理与维护,
 * 特别是对于一些配置类,多实例总会出现一些意想不到的错误。
 * 
 * 
 * 
 * @author 
 *
 */

使用情景

/**
 * 使用情景:
 * 读取配置文件进内存
 * 我们并不需要每次都去new一个实例,然后去读文件,只需要维护一个全局的Config类,并且每次使用的时候校验下文件是否变更即可。
 * 
 * @param args
 */

一般实现

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;


//一般实现
public class Test {
	public static void main(String[] args) {
		Config config = new Config();
		System.out.println(config.getParameterA());
		System.out.println(config.getParameterB());
	}
}
class Config{
	private String parameterA;
	private String parameterB;
	public Config() {
		readConfig();
	}
	private void readConfig() {
		Properties properties = new Properties();
		InputStream is = Config.class.getResourceAsStream("test.properties");
		try {
			properties.load(is);
			this.parameterA = properties.getProperty("parameterA");
			this.parameterB = properties.getProperty("parameterB");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				is.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	public String getParameterA() {
		return parameterA;
	}
	public String getParameterB() {
		return parameterB;
	}
	
}
/*
 * 问题
 * 如果在系统运行过程中,多出用到配置文件,就需要创建很多Config对象
 * 对资源有很大的浪费。
 */

单例模式实现

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

//单例模式实现
public class Test2 {
	public static void main(String[] args) {
		Singleton_Config sc1 =Singleton_Config.getInstance();
		sc1.readConfig();
		System.out.println(sc1.getParameterA());
		System.out.println(sc1.getParameterB());
		Singleton_Config sc2 =Singleton_Config.getInstance();
		System.out.println(sc1 == sc2);
	}
}	

class Singleton_Config{
	private static Singleton_Config instance;
	private String parameterA;
	private String parameterB;
	private Singleton_Config() {
		
	}
	public void readConfig() {
		Properties properties = new Properties();
		InputStream is = Config.class.getResourceAsStream("test.properties");
		try {
			properties.load(is);
			this.parameterA = properties.getProperty("parameterA");
			this.parameterB = properties.getProperty("parameterB");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				is.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	public static Singleton_Config getInstance() {
		if(instance == null) {
			instance = new Singleton_Config();
			return instance;
		}else {
			return instance;
		}
	}
	public String getParameterA() {
		return parameterA;
	}
	public String getParameterB() {
		return parameterB;
	}
	
}

/*
 * 这种实现方法很容易发现一个问题,就是在多线程访问时会造成线程不安全
 */
//模板代码
class Singleton{
	private static Singleton instance;
	private Singleton() {
		
	}
	public static Singleton GetInstance() {
		if(instance == null) {
			instance =new Singleton();
		}
		return instance;
	}
}
public class Client{
	public static void main(String[] args) {
		Singleton s1 = Singleton.GetInstance();
	}
}

多线程的情况

/*
 * 多线程中的单例模式
 * 多线程访问时,单例类相当于临界资源,还是可能创建多个对象
 * 这时可以采用线程锁的方式解决该问题
 */

//双重锁模式
public class Test3 {
	public static void main(String[] args) {
		Runnable r =() ->{
			Singleton s =Singleton.getSingleton();
			System.out.println(s.toString());
		};
		Thread t1 = new Thread(r);
		Thread t2 = new Thread(r);
		Thread t3 = new Thread(r);
		t1.start();
		t2.start();
		t3.start();
		
	}
}

class Singleton {

	private static Singleton singleton;

	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 Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}
//饿汉模式
public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}
//静态内部类单例模式
public class Singleton { 
    private Singleton(){
    }
      public static Singleton getInstance(){  
        return Inner.instance;  
    }  
    private static class Inner {  
        private static final Singleton instance = new Singleton();  
    }  
} 
/*只有第一次调用getInstance方法时,虚拟机才加载 Inner 并初始化instance ,只有一个线程可以获得对象的初始化锁,其他线程无法进行初始化,保证对象的唯一性。目前此方式是所有单例模式中最推荐的模式,但具体还是根据项目选择。
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值