java收集程序员Java学习笔记

单例模式

2016-12-21  本文已影响84人  司鑫

1 简介


单例模式是一种对象创建型模式。单例模式保证一个类只有一个实例存在,并且同时提供一个全局的方法进行进行访问该实例。

应用场景

2 几种实现方式


2.1 饿汉式

所谓饿汉式,就是不管三七二十一,一上来就开干。不管你需不需要创建某个对象,只要在加载类的时候就创建。

我要吃吃吃吃

** - 实现方式**

实体类:Person.class

public class Person {
    private String name;
    private Integer age;
    <!-在Person被加载的时候Person对象就被创建-!>
    private static Person person = new Person();
<!--使用private ,防止用户利用空参构造器进行实例化--!>
    private Person(){
        
    }
    public static Person getPerson(){
        return person;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
}

MainClass.class

public class MainClass {
    public static void main(String[] args) {
        Person person = Person.getPerson();
        person.setAge(20);
        person.setName("HAH");
        System.out.println(person.getName());
    }
}

在类加载时就实例化对象,这样可以保证该对象的唯一性,是线程安全的,但是相对的效率可能会降低,因为用户也许就不需要实例化该对象。

2.2 懒汉式

所谓懒汉式,顾名思义,就是用到的时候在创建。也就是说,在类加载的时候不会实例化对象,只有当用户真正的要创建对象的时候再调用方法实例化对象。


哪位湿兄可以帮我盖下被子QAQ

- 实现方式

Peison.class

public class Person {
    private String name;
    private Integer age;
    <!--类加载时不会实例化对象--!>
    private static Person person = null;
    private Person(){
        
    }
<!-用户第一次调用getPerson时会创建对象,以后都不需要创建-!>
    public static Person getPerson(){
        if(person == null){
            person = new Person();
        }
        return person;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }   
}

可见,使用懒汉式可以提高程序的灵活性。但是这样也存在一个很大的缺陷。当第一次调用getPerson( )方法时有多个线程同时访问时,那么就会出现线程同步问题。所以的我们需要在方法上加上synchronized防止多个线程同时访问。

** - 改进**

Person.class

public class Person {
    private String name;
    private Integer age;
    
    private static Person person = null;
    private Person(){
        
    }
<!-在方法上加上synchronized保证当前方法同一时间点只能有一个线程访问-!>
    public static synchronized Person getPerson(){
        if(person == null){
            person = new Person();
        }
        return person;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
}

在给getPerson( )方法上加上synchronized可以避免多个线程第一次同时访问实例化多个对象,但是这样在方法上加上synchronized会大大的降低程序的效率,因为只有第一次调用getPerson( )方法时才会发生线程问题,而第二次及以后调用均不会发生线程问题,这样当有一个线程调用getPerson( )方法时,其它线程都将被阻塞,直到调用方法的线程调用完毕。

2.3 双重检查

双重检查既是在懒汉式的改进基础上进行改进,对实例化对象的代码加锁并加以判断,从而实现线程安全并且和懒汉式相比效率也大大提高。

- 具体实现

Person.class

public class Person {
    private String name;
    private Integer age;
    
    private static Person person = null;
    private Person(){
        
    }
    public static  Person getPerson(){
        if(person == null){                               (1
<!--将实例化对象的代码加锁--!>
            synchronized(Person.class){      (2
<!-防止第一次调用getPerson方法时多个线程同时进入 (1,当第一线程创建完对象释放锁后,
后面的线程获得锁多次创建对象-!>
                if(person == null){
                    person = new Person();
                }
            }
            
        }
        return person;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
}

3 三种实现方式的比较


最近刚学设计模式,哪理解错了,望各位湿兄大佬多多指正

上一篇:抽象工厂模式
下一篇:原型模式

上一篇 下一篇

猜你喜欢

热点阅读