单例模式:则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。
核心的知识点:
1.private构造方法,防止通过new关键字,实例化出实例来。
2.再其内部产生该类的实例化对象,并用public static修饰。
3.写一个static方法,返回该实例对象。
一共介绍四种方式,前三种了解就可以了,随后一种为单例模式中的最优解。
1.饿汉式Singleton
//优点:写法简单,线程安全
//缺点:实例一直存在于内存中,会造成内存的浪费
public class SingletonTest {
//构造方法写成private 防止通过 new SingletonTest()来创建实例
private SingletonTest(){
}
//饿汉式,用fianl关键字修饰
private static final SingletonTest instance = new SingletonTest();
public static SingletonTest getSingletonInstance(){
return instance;
}
}
2.饱汉式Singleton
//优点:写法简单,某些情况下节约内存
//缺点:并发的环境下会出现多个SingletonTest2实例,非线程安全
public class SingletonTest2 {
//构造方法写成private 防止通过 new SingletonTest()来创建实例
private SingletonTest2(){
}
//饱汉式,没有使用final关键字
private static SingletonTest2 instance;
public static SingletonTest2 getSingletonInstance(){
if(instance == null)
new SingletonTest2();
return instance;
}
}
3.
饱汉式Singleton:使用synchronize关键字优化了非线程安全的问题
//缺点:同步方法频繁调用,效率低
public class SingletonTest3 {
//构造方法写成private 防止通过 new SingletonTest()来创建实例
private SingletonTest3(){
}
//饱汉式,没有使用final关键字
private static SingletonTest3 instance;
//调用时再初始化SingletonTest3,使用synchronized避免多线程访问时,可能造成重的复初始化问题)
public static synchronized SingletonTest3 getSingletonInstance(){
if(instance == null)
new SingletonTest3();
return instance;
}
}
4.单例模式的最优解
//单例模式的最优方案
public class SingletonTest4 {
//构造方法写成private 防止通过 new SingletonTest()来创建实例
private SingletonTest4(){
}
//饱汉式,没有使用final关键字
//用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最新的值
//使用volatile保证了多线程访问时instance变量的可见性,避免了instance初始化时其他变量属性还没赋值完时,被另外线程调用
private static volatile SingletonTest4 instance;
public static SingletonTest4 getSingletonInstance(){
//instance不等于null时,直接返回对象,提高运行效率
if(instance == null)
//同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建)
synchronized (SingletonTest4.class) {
instance = new SingletonTest4();
}
return instance;
}
纸上得来终觉浅。。。
快乐学习,快乐编程!