首页 > 代码库 > Java-设计模式-单例模式-饿汉模式、懒汉模式

Java-设计模式-单例模式-饿汉模式、懒汉模式

//-------------------------------------------------------------饿汉模式--开始-----------------------------------------------------------
package com.study.DesignPattern01;
/**
 * 创建一个饿汉模式的单例
 * @author ZLHome
 *有些对象,我们只需要一个,如果多了,那么就可能导致数据不一致,
    占用资源过多等等,比如:
        配置文件、工具类、线程池、缓存、日志对象
 */
public class Singleton {
    //1、构造方法私有化(这样类就不能被实例化了)
    private Singleton(){
        System.out.println("实例化Singleton类");
    }
    
    //2、实例化单例对象,对象为静态的(这样就只会实例化一次),私有的(安全,外部不能直接Singleton.instance调用)
    private static Singleton instance = new Singleton();
    
    //3、提供一个静态方法(静态方法,类可以直接调用),用于获取单例
    public static Singleton getInstance(){
        return instance;
    }
}
//---------------------------------------------------------------------------------------------
package com.study.DesignPattern01;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class SingletonTest {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        System.out.println("Junit开始BeforeClass...");
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        System.out.println("Junit过后AfterClass...");
    }

    @Before
    public void setUp() throws Exception {
        System.out.println("Junit开始Before...");
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("Junit过后After...");
    }

    @Test
    public void test() {
        System.out.println("Junit开始...");
        Singleton instance = Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        System.out.println("是否相等:"+(instance==instance1));
    }

}
//-------------------------------------------------------------饿汉模式--结束-----------------------------------------------------------



//============================================================懒汉模式--开始============================================================
package com.study.DesignPattern01;

public class Singleton1 {
    //1、将构造方法设置为私有(这样类就不能被外部实例化了)
    private Singleton1(){
        System.out.println("实例化Singleton1");
    }
    
    //2、申明单例对象
    private static Singleton1 instance;
    
    //3、提供一个静态方法(静态方法属于类),用于外部调用
    public static Singleton1 getInstance(){
        if(instance==null){
            System.out.println("第一次实例化Singleton1对象");
            instance=new Singleton1();
        }
        return instance;
    }
}


//============================================================

package com.study.DesignPattern01;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class Singleton1Test {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        System.out.println("Junit开始BeforeClass...");
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        System.out.println("Junit过后AfterClass...");
    }

    @Before
    public void setUp() throws Exception {
        System.out.println("Junit开始Before...");
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("Junit过后After...");
    }

    @Test
    public void test() {
        System.out.println("Junit开始...");
        Singleton1 instance = Singleton1.getInstance();
        Singleton1 instance1 = Singleton1.getInstance();
        System.out.println("是否相等:"+(instance==instance1));
    }

}


//============================================================懒汉模式--结束============================================================

 

设计模式
可靠性更高、更容易理解、扩展性更好‘更容易维护
1、单例模式:
1)单例背景、情况:
有些对象,我们只需要一个,如果多了,那么就可能导致数据不一致,
占用资源过多等等,比如:
配置文件、工具类、线程池、缓存、日志对象
2)原理:
实例化对象是通过构造方法来实现的(程序类未写,则程序类有默认的构造方法),
单例只允许获取一个实例,所以

饿汉模式:
类加载的时候就实例化对象(比较饿,主动实例对象)
(1)实现单例就去改写构造方法:将构造方法改写为私有的,改写之后,就不能直接实例化了(不允许外部直接创建实例)
(2)创建类的唯一实例(类里面去new一个实例,且这个实例是static[变量、方法加static后就变成类所有,不是必须创建实例对象来调用],这样就可以通过类直接调用这个实例[类名.实例变量名])
(3)为了安全,不允许外部直接访问成员变量,所以(2)需要优化,将类的static实例变为private,变为private之后就不能直接通过"类名.实例变量名"来访问了,所以提供类的方法get,类的get方法也需要是static才能通过"类名.方法名"调用

懒汉模式:
类加载的时候只是声明一下,调用这个单例的时候才实例化(比较懒,不主动去实例对象)
(1)先声明一个单例,并不实例化单例对象
(2)在get方法里面去判断,如果没有实例这个对象,就将单例对象实例化再返回

对比:
懒汉模式:类加载快,获取对象慢,线程安全的
饿汉模式:类加载慢,获取对象快,线程不安全

总结:static修饰的变量、方法数据类,可以通过类直接调用

Java-设计模式-单例模式-饿汉模式、懒汉模式