Java-设计模式-单例模式-饿汉模式懒汉模式
Posted 第二天半
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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-设计模式-单例模式-饿汉模式懒汉模式的主要内容,如果未能解决你的问题,请参考以下文章
java软件设计模式——单例设计模式中的饿汉式与 懒汉式示例
Java 设计模式 -- 单例模式的实现(饿汉式枚举饿汉式懒汉式双检锁懒汉式内部类懒汉式)jdk 中用到单例模式的场景DCL实现单例需用volatile 修饰静态变量