单例模式分为懒汉式和饿汉式。
所谓单例模式,就是构造器私有化,对外界提供唯一的一份实例。
- 懒汉式)(线程不安全)
懒汉式在程序需要运行的时候再加载,这样保证程序内存空间不会被浪费
public class Test {
public static void main(String [] args){
person p=person.getInstance();
person p1=person.getInstance();
System.out.println(p==p1);
}
}
class person{
private static person p;//所要向外界提供的一份实例
private person(){};//构造器私有化
public static person getInstance(){
/*getInstance方法在主函数开始时调用,返回一个实例化对象,此对象是static的,
在内存中保留着它的引用,即内存中有一块区域专门用来存放静态方法和变量,
可以直接使用,调用多次返回同一个对象。所以person p对象必须是静态的才能放进这个方法。*/
if(p==null){//第一次调用时如果对象没有创建,则创建唯一的一份实例
p=new person();
}
return p;
}
}
- 饿汉式(安全(上了锁)占用资源,内存消耗大)
public class Test {
public static void main(String [] args){
person p=person.getInstance();
person p1=person.getInstance();
System.out.println(p==p1);
}
}
class person{
private static person p;//所要向外界提供的一份实例
private person(){};//构造器私有化
public static person getInstance(){
/*getInstance方法在主函数开始时调用,返回一个实例化对象,此对象是static的,
在内存中保留着它的引用,即内存中有一块区域专门用来存放静态方法和变量,
可以直接使用,调用多次返回同一个对象。所以person p对象必须是静态的才能放进这个方法。*/
if(p==null){//第一次调用时如果对象没有创建,则创建唯一的一份实例
synchronized (person.class) {
if (p == null) {
p = new person();
}
}
}
return p;
}
}
饿汉式就是在懒汉式的基础上家里同步锁,假设有A,B两条线程同时想要用person实例,A线程刚判断完pnull,B就抢占了线程,然后走完全部程序创建了一份实例,释放锁。然后A才抢到线程,上锁后如果直接创建则浪费内存空间,所以他上锁之后还得判断pnull,这样双重判断才能保证线程安全。