单例模式
简单说:一个对象只有一个对象实例
饿汉式(静态常量):
饿汉式(饥饿,一上来就想吃,一装载就实例化)
三步:
1.构造器私有化(外部不能通过new来新建一个对象实例)
2.类内部创建一个对象实例
3.提供一个共有的静态方法(供外部调用):返回实例对象
代码示例和注解:
/*
* 单例模式:
* 饿汉式(静态常量)
* 1.构造器私有化(外部不能通过new来新建一个对象实例)
* 2.类内部创建一个对象实例
* 3.提供一个共有的静态方法(供外部调用):返回实例对象
*
* 优缺点:这种方法是在类装载的时候就将对象实例化(类的加载只会执行一次,下次再创建对象时,可以直接在方法区中获取class信息),(这种方式基于classLoad机制,classLoad的loadClass()方法默认是同步的,线程安全的,所以是避免线程同步问题)避免了线程同步问题
* 这种方法可用,但是可能造成内存浪费(因为类装载的时候就进行了对象实例化,也就没有达到lazy loading(懒加载)的效果,如果从始至终都没有用过这个实例,那么就会造成内存浪费)
*/
public class Singleton {
public static void main(String[] args){
SingletonTest instance = SingletonTest.getInstance();
SingletonTest instance2 = SingletonTest.getInstance();
System.out.println(instance == instance2);//true
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
//打印结果:
//true
//366712642
//366712642证明只创建了一个对象实例
}
}
class SingletonTest{
//构造器私有化
private SingletonTest(){
}
//创建对象实例
private final static SingletonTest instance = new SingletonTest();
//提供一个共有的静态方法
public static SingletonTest getInstance(){
return instance;
}
}
优缺点:
优点: 这种方法是在类装载的时候就将对象实例化(类的加载只会执行一次,下次再创建对象时,可以直接在方法区中获取class信息),(这种方式基于classLoad机制,classLoad的loadClass()方法默认是同步的,线程安全的,所以是避免线程同步问题)避免了线程同步问题
缺点: 这种方法可用,但是可能造成内存浪费(因为类装载的时候就进行了对象实例化,也就没有达到lazy loading(懒加载)的效果,如果从始至终都没有用过这个实例,那么就会造成内存浪费)
饿汉式(静态代码块):
/*
* 单例模式:
* 饿汉式(静态代码块)
* 1.构造器私有化(外部不能通过new来新建一个对象实例)
* 2.类内部创建一个对象实例(实例化放在静态代码块中)
* 3.提供一个共有的静态方法(供外部调用):返回实例对象
*
* 优缺点:这种方法也是是在类装载的时候就将对象实例化,只不过将对象实例化放在了静态代码块中,避免了线程同步问题
* 这种方法可用,但是可能造成内存浪费(因为类装载的时候就进行了对象实例化,也就没有达到lazy loading(懒加载)的效果,如果从始至终都没有用过这个实例,那么就会造成内存浪费)
*/
public class Singleton {
public static void main(String[] args){
SingletonTest instance = SingletonTest.getInstance();
SingletonTest instance2 = SingletonTest.getInstance();
System.out.println(instance == instance2);//true
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
//true
//366712642
//366712642证明只创建了一个对象实例
}
}
class SingletonTest{
//构造器私有化
private SingletonTest(){
}
//创建对象实例
private static SingletonTest instance;
static{
instance = new SingletonTest();
}
//提供一个共有的静态方法
public static SingletonTest getInstance(){
return instance;
}
}