1. 单例模式
保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
优点:
– 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要 比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动 时直接产生一个单例对象,然后永久驻留内存的方式来解决
– 单例模式可以在系统设置全局的访问点,优化环共享资源访问,例如可以设计 一个单例类,负责所有数据表的映射处理
1、懒加载(静态内部类)
public class Singleton{
private Singletion{
}
private static class T{
///静态内部类在使用的时候才加载,且只加载一次
private static final Singleton t = new Singleton();
}
public static Singleton getInstance(){
return T.t;
}
}
– 外部类没有static属性,则不会像饿汉式那样立即加载对象。
– 只有真正调用getInstance(),才会加载静态内部类。加载类时是线程 安全的。 instance是static final 类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性.
– 兼备了并发高效调用和延迟加载的优势!
2、双重校验锁
package ss;
public class Singleton4 {
private Singleton4(){
}
private static volatile Singleton4 s = null;
public static Singleton4 getInstence(){
if(s==null){
synchronized (Singleton4.class) {
if(s==null){
s = new Singleton4();
}
}
}
return s;
}
}
现在想象一下有线程 A 和 B 在调用 getInstance(),线程 A 先进入,在 执行到 instance=new Singleton():的时候被踢出了 cpu。然后线程 B 进入,B 看到的是 instance 已经不是 null 了(内存已经分配),于是它开始放心地使用 instance,但这个是错误的,因为 A 还没有来得及完成 instance 的初始化,而线 程 B 就返回了未被初始化的 instance 实例(为了禁止指令重排序,就用 volatile 关键字)。
3、 饿汉式(单例对象立即加载)
public class Singleton{
private static Singleton s = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return s;
}
}
饿汉式单例模式代码中,static变量会在类装载时初始化,此时也不会涉及多个线程对象访问该对象的问 题。虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题。因此,可以省略synchronized关键字。
4、懒汉式(单例对象延时加载)
public class Singleton{
private static Singleton s;
private Singleton()