**
单例模式
分为-
饿汉式
懒汉式
双重检测锁式(了解即可)
静态内部类
枚举类型
**
我们要实现单例模式有哪些存在问题呢?
1.new才能创建对象,并且可以无数个new
2.不让调用者去new对象
3.new是构造方法,我们要把构造方法私有化
·
实现步骤:
1.私有化构造方法
2.私有化静态实例方法
3.对外提供公共访问方法
饿汉式
实现类
//饿汉式没有延时加载
public class Single {
private static Single s = new Single();//私有化实例方法,保证只有一个实例
private Single() {}//私有化构造方法
public static Single getSingle() {//对外提供访问方法
return s;//返回给私有化的实例方法对象
}
}
测试类
public class Test {
public static void main(String[] args) {
//类名.方法名创建实例方法
//返回的相同内存地址,因为方法区的静态块只有一个实例化的s对象,在堆内存中只有唯一一个s对象
Single s1 =Single.getSingle();
Single s2 =Single.getSingle();
Single s3 =Single.getSingle();
System.out.println(s1==s2);//true
System.out.println(s1==s3);//true
System.out.println(s2==s3);//true
}
}
图片返回都是true,说明了在方法区的静态块只有一个实例化的s对象。在堆内存中只有唯一一个s对象,在测试类进行调用的都是实例化的s对象。
懒汉式
实现类:
//懒汉式有延时加载
public class Singleton {
private static Singleton s;
private Singleton() {
if(s!=null) {//如果不是null,抛出异常
throw new RuntimeException();
}
}
//synchronized是线程同步锁,保证同一时间内只能有一个线程访问一个代码块的关键字
public static synchronized Singleton getSingleton() {//提供功公共的访问方法
if(s==null) {//判断s是null,才创建实例,可以节省内存空间
s=new Singleton();
}
return s;
}
}
测试类:
public class Test {
public static void main(String[] args) {
//类名.方法名创建实例方法
//返回的相同内存地址,因为方法区的静态块只有一个实例化的s对象,在堆内存中只有唯一一个s对象
Singleton s1 = Singleton.getSingleton();
Singleton s2 = Singleton.getSingleton();
Singleton s3 = Singleton.getSingleton();
System.out.println(s1==s2);//true
System.out.println(s1==s3);//true
System.out.println(s2==s3);//true
}
}
静态内部类:
实现类
//静态内部类属于懒加载
public class Single {
private Single() {};//私有化构造函数
private static class SingleIN{//创建静态内部类,创建实例
private static final Single s=new Single();//final表示只能创建一个实例
}
public static Single getSingle() {
return SingleIN.s;//返回方法的的实例对象
}
public void run() {//自定义方法
System.out.println("我是小烁烁");
}
}
测试类
public class Test {
public static void main(String[] args) {
Single s = Single.getSingle();
s.run();//可以调用方法,说明创建了实例
}
}
枚举:
实现类:
public enum Singletom {//enum有且仅有private的构造器,防止外部额外构造
INSTANCE;//枚举关键字,相当于将Singletom实例了
public void speak() {
System.out.println("小烁烁在喝茶!");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Singletom s = Singletom.INSTANCE;
s.speak();//能够调用方法,说明实例获取到了
}
}