1.单例模式概念:
单例模式是一种常用的设计模式,通过单例模式在内存中只能存在一个该类对象,即只能有一个实例,并且该实例易于外界访问.
2.什么时候使用单例模式
第一、控制资源的使用,通过线程同步来控制资源的并发访问;
第二、控制实例产生的数量,达到节约资源的目的。
第三、作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信
3.常用单例模式:
饿汉式:对象的初始化过程在类加载的时候就已经完成
懒汉式:调用方法的时候再创建对象.
4.饿汉式单例模式的代码实现:
public class Singleton1 {
// 私有化构造方法,是不让外界随意创建
private Singleton1() {}
// 定义私有的静态成员
private static Singleton1 s1 = new Singleton1();
// 提供公有的静态工厂方法,让外界能够直接通过类名访问该方法
public static Singleton1 getInstance() {
return s1;
}
}
5.懒汉式单例模式代码实现:
public class Singleton2 {
// 私有化构造方法,不让外界随意创建
private Singleton2() {}
private static Singleton2 s2 = null;
// 提供公有的静态工厂方法,让外界能够直接通过类名访问该方法
public static Singleton2 getInstance() {
if(s2==null){
s2=new Singleton2();
}
return s2;
}
}
6.懒汉式单例模式中的线程安全问题
懒汉式单例模式需要考虑线程安全问题,否则并发情况下可能会出现多个Singleton实例,解决方式有两种.
(1).在getInstance方法上加锁
public synchronized static Singleton1 getSingleton1() {
if(s1==null){
s1=new Singleton1();
}
return s1;
}
该方式虽然线程安全,但是每次都需要同步,会严重影响性能.
(2)双重检查锁定
public static Singleton2 getInstance() {
if(s2==null){
synchronized(Singleton2.class){
if(s2==null){
s2=new Singleton2();
}
}
}
return s2;
}
该方式确保只有在第一次调用单例的时候才同步,既确保了其同步安全,也避免了每次都同步的性能损耗.
主函数中进行测试
public class Test {
public static void main(String[] args) {
Singleton2 s1=Singleton2.getInstance();
s1.setName("张三");
Singleton2 s2=Singleton2.getInstance();
s2.setName("李四");
System.out.println(s1.getName());
System.out.println(s2.getName());
if(s1==s2){
System.out.println("创建同一个实例");
}else{
System.out.println("创建的不是同一个实例");
}
}
}
结果:
李四
李四
创建同一个实例
7.结论:
单例模式为程序提供一个唯一的对象,不管它实现什么功能,程序会同时共享该唯一对象.