设计模式——单例模式
一、介绍
设计模式更多的是思想层面,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了使代码高可用,易于他人理解以及保证代码的可靠性。
设计模式有23中:单例模式、抽象工厂模式、工厂模式、建造者模式、原型模式等。
单例模式(使用单例模式就是为了保证整个应用中某个实例有且只有一个):
在程序开发中,有些对象只需要一个,比如:配置文件、工具类、线程池、缓存、日志对象等;如果创建多个对象,会导致很多问题,比如资源占用,结果不一致等等。
二、实现
单例模式(Singleton):
饿汉模式(静态成员属类所有,加载类时,就会创建类的唯一实例,不管用户是否使用这个实例,它已经被加载,形象的称之为“饿汉模式”):
public class Singleton{ //默认的构造方法在创建对象时被调用;多次new则创建多个类对象 //1、私有化构造方法(外部无法直接通过构造方法创建实例,避免创建多个实例) private Singleton(){} //2、保证实例只有一个,自己创建实例(创建类的唯一实例,使用private static修饰类的静态成员) //因外部类无法直接使用对象.成员方法(),所以使用static静态修饰对象,用类名.成员名创建实例 //为了控制访问、安全,加private不允许外部访问成员变量,不能使用类名.成员名创建实例 private static Singleton instance = new Singleton(); //3、提供一个用于获取实例的方法(属于对象方法,不用static修饰的话无法用类名.方法创建实例) /*public Singleton getInstance(){ return instance; }*/ //使用public static修饰类方法 public static Singleton getInstance(){ return instance; } }
public class Test{ public static void main(String[] args){ //私有化构造方法后,外部类无法直接创建实例 /*Singleton s1 = Singleton.instance;//调用静态成员创建实例 Singleton s2 = Singleton.instance;//调用静态成员创建实例 if(s1==s2){//true 保证创建的Singleton对象是单个实例 System.out.println("s1和s2是同一个实例"); }else{ System.out.println("s1和s2不是同一个实例"); }*/ //调用失败,方法是对象方法(没有用static修饰的方法) /*Singleton s1 = Singleton.getInstance();*/ Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); if(s1==s2){//true 保证创建的Singleton对象是单个实例 System.out.println("s1和s2是同一个实例"); }else{ System.out.println("s1和s2不是同一个实例"); } } }
懒汉模式(类加载时不创建唯一实例,当第一个用户获取时判断实例为空时时创建,之后所有用户获取已经存在的实例将不再创建):
public class Singleton2{ //1、私有化构造方法,不允许外部直接通过构造方法创建对象 private Singleton2(){} //2、声明类的唯一实例,使用private static 修饰 private static Singleton2 instance ; //3、提供一个用于获取实例的方法,使用public static修饰 public static Singleton2 getInstance(){ if(instance == null){ instance = new Singleton2(); } return instance; } }
public class Test{ public static void main(String[] args){ Singleton2 s3 = Singleton2.getInstance(); Singleton2 s4 = Singleton2.getInstance(); if(s3==s4){//true 保证创建的Singleton对象是单个实例 System.out.println("s3和s4是同一个实例"); }else{ System.out.println("s3和s4不是同一个实例"); } }
三、区别
饿汉模式加载类时比较慢,运行时获取对象速度比较快,线程安全;
懒汉模式加载类时比较快(加载类时没有创建类的对象),但运行时获取对象速度比较慢(用户第一次获取对象时由于类还没有被创建,需要创建对象的一个过程),线程不安全。
Singleton
Singleton 懒汉式
Singleton 饿汉式
配置文件/工具类/线程池/缓存/日志对象等
Design Pattern
添加static 让他变为类所有,不再是对象方法,可以通过类名直接访问
public static Singleton getInstance(){}
Singleton s1=Singleton.getInstance();
设计模式目的
饿汉模式的特点是加载类时比较慢,但运行时获取对象的速度比较快
懒汉模式的特点是加载类时比较快,但运行时获取对象的速度比较慢
饿汉模式加载类慢,运行时获取对象快,线程安全
懒汉模式加载类快,运行时获取对象慢,线程不安全
使用设计模式的为了可重用代码、让代码更容易被他人理解、保证代码可靠性
设计模式:是一套被反复使用、所属人知晓的、经过分类编目的、代码设计经验的总结
单例模式 --- 懒汉模式
class Singleton { //1.将构造方法私有化,使外部无法直接创建对象 private Singleton() { } //2.创建类的唯一实例 private static Singleton instance; //3.提供获取实例的方法 public static Singleton getInstance() { if(instance==null){ instance = new Singleton(); } return instance; } }
特点:在第一次调用时,实例化对象。(特点加载类较快,调用较慢)
单例模式 --- 饿汉模式
class Singleton { //1.将构造方法私有化,使外部无法直接创建对象 private Singleton() { } //2.创建类的唯一实例 private static Singleton instance = new Singleton(); //3.提供获取实例的方法 public static Singleton getInstance() { return instance; } }
特点:在加载类时实例化对象。(加载类较慢,但调用较快)
//区别:饿汉模式的特点是加载类时比较慢,但运行时获取对象的速度比较快,线程安全
//懒汉模式的特点是加载类时比较快,但运行时获取对象的速度比较慢,线程不安全
//单例模式:懒汉模式
public class Singleton2{
//1、将构造方式私有化,不允许外边直接创建对象
private Singleton2(){}
//2、创建类的唯一实例,使用private static修饰
private static Singleton2 instance;
//3、提供一个用于获取实例的方法,使用public static修饰
public static Singleton2 getInstance(){
if(instance==null)
{
instance=new Singleton2();
}
return instance;
}
}
public class Test{
public static void main(String[] args)
{
Singleton s1=Singleton2.getInstance();
Singleton s2=Singleton2.getInstance();
if(s1==s2)
{
System.out.println("s1和s2是同一个实例");
}else{
System.out.println("s1和s2不是同一个实例");
}
}
}
//单例模式:饿汉模式
public class Singleton{
//1、将构造方法私有化,不允许外部直接创建对象
private Singleton(){}
//2、创建类的唯一实例,使用private static修饰
private static Singleton instance=new Singleton();
//3、提供一个用于获取实例的方法
public static Singleton getInstace()
{
return instance;
}
}
public class Test{
public static void main(String[] args)
{
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
if(s1==s2)
{
System.out.println("s1和s2是同一个实例");
}else{
System.out.println("s1和s2不是同一个实例");
}
}
}
设计模式:懒汉模式、饿汉模式
目的:可重用代码、易理解、保证代码可靠性
单例模式使用:在有些对象我们只需要一个的时候,比如:配置文件、工具类、线程池、缓存、日志对象等。如果创造多个实例,就会导致许多问题,比如占用过多资源,不一致的结果等。
单例模式 1:饿汉模式,加载慢,获取快,线程安全 2:懒汉模式,加载快,获取慢,线程不安全 单列模式分为: 饿汉式:声明的同时直接实例化。 特点:加载类时比较慢,但运行时获取对象的速度比较快,线程安全。 懒汉式:声明的时候不实例化。 特点:加载类时比较快,但运行时获取对象的速度比较慢,线程不安全。 实现单列模式的三个步骤: 1、将构造方法私有化,不允许外界直接创建对象。 2、声明类的唯一实例,使用private static修饰。 3、提供一个供外界获取实例的方法,使用public static修饰。