概念
- 个人定义
单例模式是为了高效利用一个类, 避免类重复创建 , 避免类重复创建,高效利用电脑的CPU,防止jvm频繁GC.
- 官方点的定义
单例模式是一种对象创建模式,它用于产生有一个对象的具体事例,它确保一个类中在系统中只有一个实例模式, 从而令new 的操作次数减少,降低对系统内存的频繁使用,减轻GC压力,缩短GC停顿时间.
饿汉式
把无参数构造方法私有化,外部不能创建对象,类自身首先创建自己的成员变量,通过静态方法getInstance方法获取类的实例,这就是饿汉式写法,可以这么理解,饿汉迫不及待的创建自己,因为饿的昏头昏脑了,很迫不及待提供自己来填饱自己的肚子,所以很形象化的称呼这种形式的单例模式写法为饿汉式.
public class HungrySingleton {
private static final HungrySingleton mHungrySingleton=new HungrySingleton();
private HungrySingleton (){
System.out.println("Singleton is create");
}
public static HungrySingleton getInstance(){
return mHungrySingleton;
}
public static void main(String[] args) {
System.out.println("main method is operating");
}
//代表创建的成员变量,他们每次创建都会占用很多内存
private String mName;
private int mAge;
public String getmName() {
return mName;
}
public void setmName(String mName) {
this.mName = mName;
}
public int getmAge() {
return mAge;
}
public void setmAge(int mAge) {
this.mAge = mAge;
}
}
饿汉式的缺点
上边我们已经总结了饿汉式单利模式的优点,但是这种形式的写法有一个缺点,我们执行上边的代码的main方法结果如下.
Singleton is create
main method is operating
我们没有外部的类来调用我们写的这个饿汉式单例类,但是他还是会创建自己,不能延时创建自己从而造成了占用过多内存空间,这是我们不想看到的结果,我们如何解决呢? 下边我们做一下优化,让单例类延时创建自己,懒汉式写法.
懒汉式写法+懒汉式线程安全方法
为了解决延时加载,我们首先不是上来就创建单例对象的实例赋值给变量,当你调用getInstance方法的时候才创建实例对象并赋值给创建好的成员变量.
public class SafeLazySingleton {
public static final SafeLazySingleton sLazySingleton =null;
private SafeLazySingleton(){
System.out.println("Singleton is create");
}
public static SafeLazySingleton getInstance(){
//良好的代码习惯,我们可以复用,进一步优化
if(null==sLazySingleton){
return new SafeLazySingleton();
}
return sLazySingleton;
}
public static void main(String[] args) {
System.out.println("LazySington is operation");
}
}
让我们测试一下,执行一下main方法
LazySington is operation
构造方法没有再次执行,我们就到此为止了吗? Java最头疼的问题之一,是不是高并发,他是否能经得起高并发的考验,我们用如下代码测试一下.
public class SafeLazySingleton {
public static SafeLazySingleton sLazySingleton =null;
private SafeLazySingleton(){
System.out.println("Singleton is create");
}
//给方法加锁
public static synchronized SafeLazySingleton getInstance(){
//良好的代码习惯,我们可以复用,进一步优化
if(null==sLazySingleton){
sLazySingleton=new SafeLazySingleton();
}
return sLazySingleton;
}
public static SafeLazySingleton getInstance1(){
//利用代码块来进行加锁
synchronized (LazySingleton.class) {
//良好的代码习惯,我们可以复用,进一步优化
if(null==sLazySingleton){
sLazySingleton=new SafeLazySingleton();
}
}
return sLazySingleton;
}
public static void main(String[] args) {
System.out.println("LazySington is operation");
}
}
通过给方法加锁或者利用代码块进行对类进行加锁 ,我们用getInstance和gitInstance1方法得到的结果如下,都是一个类:
Singleton is create
懒汉式线程安全式: 1210420568
懒汉式线程安全式: 1210420568
懒汉式线程安全式: 1210420568
懒汉式线程安全式: 1210420568
懒汉式线程安全式: 1210420568