所谓类的单例设计模式,介绍采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。
单例模式有八种方式
1)饿汉式(静态常量)【可用】
2)饿汉式(静态代码块)【可用】
3)懒汉式(线程不安全)【不推荐】
4)懒汉式(线程安全,同步方法)【不推荐】
5)懒汉式(线程安全,同步代码块)【不推荐】
6)双重检查【推荐】
7)静态内部类【推荐】
8)枚举【推荐】
实现步骤:
1)构造器私有化(防止 new)
2)类的内部创建对象
3)向外暴露一个静态的公共方法 getInstance
4)代码实现
/**
* 饿汉式【静态常量】
* 在类装载的时候就完成实例化,可能造成内存浪费
*/
class Singleton1{
// 1、构造器私有化
private Singleton1(){}
// 2、本类内部创建对象实例
private final static Singleton1 instance = new Singleton1();
// 3、提供一个公有静态方法返回实例对象
public static Singleton1 getInstance(){
return instance;
}
}
/**
* 饿汉式【静态代码块】
* 和上面写法一样,可能造成内存浪费
*/
class Singleton2{
// 1、构造器私有化
private Singleton2(){}
// 2、本类内部创建对象实例
private final static Singleton2 instance;
// 3、在静态代码块中创建单例对象
static {
instance = new Singleton2();
}
// 4、提供一个公有静态方法返回实例对象
public static Singleton2 getInstance(){
return instance;
}
}
/**
* 懒汉式【线程不安全】
* 起到了懒加载的效果,但是只能在单线程下使用
* 实际开发中,不要使用这种方式
*/
class Singleton3{
// 1、构造器私有化
private Singleton3(){}
// 2、本类内部创建对象实例
private static Singleton3 instance;
// 3、提供一个公有静态方法,当使用到该方法时才创建instance
public static Singleton3 getInstance(){
if(null == instance){
instance = new Singleton3();
}
return instance;
}
}
/**
* 懒汉式【线程安全】
* 效率低,不推荐使用该方法
*/
class Singleton4{
// 1、构造器私有化
private Singleton4(){}
// 2、本类内部创建对象实例
private static Singleton4 instance;
// 3、提供一个公有静态方法,加入同步处理代码,解决线程安全问题
public static synchronized Singleton4 getInstance(){
if(null == instance){
instance = new Singleton4();
}
return instance;
}
}
/**
* 懒汉式【线程安全】同步代码块
* 本意是改进第四种方法,但是这种同步并不能起到线程同步问题
*/
class Singleton5{
// 1、构造器私有化
private Singleton5(){}
// 2、本类内部创建对象实例
private static Singleton5 instance;
// 3、提供一个公有静态方法,加入同步处理代码,解决线程安全问题
public static Singleton5 getInstance(){
if(null == instance){
synchronized (Singleton5.class){
instance = new Singleton5();
}
}
return instance;
}
}
/**
* 双重检测锁【线程安全】
* 线程安全且效率较高,实现了延迟加载,推荐使用
*/
class Singleton6{
// 1、构造器私有化
private Singleton6(){}
// 2、本类内部创建对象实例 volatile保证可见性,防止指令重排序
private static volatile Singleton6 instance;
// 3、提供一个公有静态方法,加入同步处理代码,解决线程安全问题
public static Singleton6 getInstance(){
if(null == instance){
synchronized (Singleton6.class){
if(null == instance){
instance = new Singleton6();
}
}
}
return instance;
}
}
/**
* 静态内部类【推荐使用】
* 1、外部类装载时静态内部类不会被装载
* 2、类的静态属性只会在第一次加载类的时候初始化,所以在这里JVM帮助
* 我们保证的线程的安全性,因为在类进行初始化时,别的线程无法进入
*/
class Singleton7{
// 1、构造器私有化
private Singleton7(){}
// 2、静态内部类;该类中有一个静态属性
private static class SingletonInstance{
private static final Singleton7 INSTANCE = new Singleton7();
}
// 3、提供一个公有静态方法直接返回SingletonInstance.INSTANCE
public static Singleton7 getInstance(){
return SingletonInstance.INSTANCE;
}
}
/**
* 枚举【推荐使用】
*/
enum Singleton8{
INSTANCE;
public void sayOk(){
System.out.println("ok");
}
}
Runtime类
public class Runtime {
private static Runtime currentRuntime = new Runtime();
/**
* Returns the runtime object associated with the current Java application.
* Most of the methods of class Runtime
are instance
* methods and must be invoked with respect to the current runtime object.
*
* @return the Runtime
object associated with the current
* Java application.
*/
public static Runtime getRuntime() {
return currentRuntime;
}
/** Don't let anyone else instantiate this class */
private Runtime() {}
......
}
1、单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能
2、当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new
3、单例模式使用的场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等)