1、饿汉模式
声明静态对象的时候初始化
public class SingleInstance {
private static SingleInstance INSTANCE=new SingleInstance();
private SingleInstance() {}
public static SingleInstance getInstance(){
return INSTANCE;
}
}
但是,因为类在第一次使用的时候会被加载到内存(如果此时没有调用 getInstance() ),因为 instance 是静态变量,也会导致单例对象被创建。
2、懒汉模式
当类第一次获取单例对象的时候初始化
public class SingleInstance {
private static SingleInstance INSTANCE;
private SingleInstance() {}
public static SingleInstance getInstance(){
if (INSTANCE==null){
INSTANCE=new SingleInstance();
}
return INSTANCE;
}
}
当然,在单线程的环境下,是没有问题的,但是如果,多线程并发访问,就会创建多个SingleInstance对象,这个时候,可以使用synchronized进行线程同步。
private static SingleInstance INSTANCE;
private SingleInstance() {}
public static synchronized SingleInstance getInstance(){
if (INSTANCE==null){
INSTANCE=new SingleInstance();
}
return INSTANCE;
}
但是,即便INSTANCE已经存在了,每次调用 getInstance()方法,都会进行同步,会降低程序的效率,可以使用同步代码块,同步关键代码
public class SingleInstance {
private static SingleInstance INSTANCE;
private SingleInstance() {}
public static SingleInstance getInstance(){
if (INSTANCE==null){
synchronized (SingleInstance.class){
if(INSTANCE==null){
INSTANCE=new SingleInstance();
}
}
}
return INSTANCE;
}
}
3、静态内部类
关于内部类
把一个类放到另一个类的内部定义,就是内部类。
- 静态内部类:如果成员内部类使用static修饰,就是静态内部类。
- 匿名内部类:如果一个类只需要使用一次,可以使用匿名内部类。创建匿名内部类时,会立即创建一个该类的实例。
记住下面几个规则:
- 静态成员(类相关)不能访问非静态成员(对象相关):外部类的静态方法,不能访问非静态内部类,即便只是调用构造器也不行,因为非静态内部类创建对象的时候,需要依赖一个外部类对象,此时它所依赖的外部对象还不存在。
- 静态内部类的实例方法,不能访问外部类的实例方法,因为静态内部类是外部类相关的,创建静态内部类对象的时候,无需创建外部类对象,此时,外部类对象还不存在。
创建对象
- 普通内部类
new out().new in() - 静态内部类
new out.in()
因为内部类,直到使用的时候才加载,即第一次调用SingleInstanceHolder.INSTANCE时,SingleInstance才会创建
public class SingleInstance {
private SingleInstance() {}
public static SingleInstance getInstance(){
return SingleInstanceHolder.INSTANCE;
}
private static class SingleInstanceHolder{
static SingleInstance INSTANCE=new SingleInstance();
}
}