优点:天然的 线程安全,不用加锁,执行效率高
缺点:没有做到懒加载,会浪费资源
四个要点:
1.私有化构造方法,让外界不能通过new关键字new出来,确保只有一个实例,并且这个实例是自己创造
2.线程安全, static 实例,具有天然的优势,
因为,static实例是在初始化时构造,而且只构造一次,所以是线程安全
3.尽可能的少加锁,因为在多线程并发的时候使用锁会导致大量的线程挂起,而使效率降低
4.尽量可以做到懒加载
5.提供一个外接可以访问的方法,访问该单例
/**
* @Author: 刘浩然
* @Date: 2020/4/25 18:16
* 单例设计模式之饥饿式设计模式
* 四个要点:
* 1.私有化构造方法,让外界不能通过new关键字new出来,确保只有一个实例,并且这个实例是自己创造
* 2.线程安全, static 实例,具有天然的优势,
* 因为,static实例是在初始化时构造,而且只构造一次,所以是线程安全
* 3.尽可能的少加锁,因为在多线程并发的时候使用锁会导致大量的线程挂起,而使效率降低
* 4.尽量可以做到懒加载
* 5.提供一个外接可以访问的方法,访问该单例
*/
public class Singleton1 {
//1.私有化构造方法
private Singleton1(){
System.out.println("饥饿式设计模式");
}
//缺点体现的地方
public static int error=5;
private static Singleton1 singleton=new Singleton1();
public static Singleton1 getInstance(){
return singleton;
}
}
class Client{
public static void main(String[] args) {
Singleton1.getInstance();
//确定不能做到懒加载,如,当使用下面的Singleton1.error调用error时,
// 会构造一个单例对象,但这时可能并没有需求
// System.out.println(Singleton1.error);
}
}
这里我们先不使用生成单例,只是使用生成单例工具类中的一个静态变量error,但是这里控制台却打印了 构造方法里的打印语句“饿汉式设计模式“ (因为静态变量和对象在初始化的时候构造只构造一次),所以这个单例对象并不是在我们真正想要使用的单例对象的时候才去构造的,而是在我们调用其他变量但没有使用单例对象意图时已经构造好了,所以我们称他为饿汉式
2。懒汉式单例设计模式
优点:1.做到懒加载(即当我们真正想要使用单例对象的时候,才去帮我们生成单例对象)
缺点:加了synchronized,使的在高并发时访问效率降低
/**
* @Author: 刘浩然
* @Date: 2020/4/25 18:34
* 二,懒汉式单例设计模式
* 优点:1.做到懒加载
* 缺点:加了synchronized,使的在高并发时访问效率降低
*/
public class Singleton2 {
private Singleton2(){
System.out.println("懒汉式设计模式");
}
public static int error=5;
private static Singleton2 singleton;
//必须要加锁,不然在多线程并发时可能导致线程不安全
//延时加载
public static synchronized Singleton2 getInstance(){
if(singleton==null){
singleton=new Singleton2();
}
return singleton;
}
}
class Client2{
public static void main(String[] args) {
Singleton2 singleton=Singleton2.getInstance();
//做到了懒加载,但是加了锁(开启下面的代码)
// System.out.println(Singleton2.error);
}
}
只有在真正要生成单例对象时才生成单例对象(懒加载)
三,静态内部类实现单例
权衡了饥饿式和懒汉式的优点
/**
* @Author: 刘浩然
* @Date: 2020/4/25 18:47
* 静态内部类-单例设计模式
*
*/
public class Singleton3 {
private Singleton3(){
System.out.println("静态内部类设计模式");
}
public static int error=5;
//实验静态内部类实现懒加载懒加载
private static class Singleton{
//天然的高并发线程安全,因为他不是在运行的时候完成构造的,他是在初始化的时候,就构造的,因为初始化只有一次机会
private static Singleton3 singleton=new Singleton3();
}
public static Singleton3 getInstance(){
return Singleton.singleton;
}
}
class Client3{
public static void main(String[] args) {
Singleton3 singleton3=Singleton3.getInstance();
// System.out.println(Singleton3.error);
}
}