Java 单例模式的二三事

单例模式-JAVA实验 这种设计模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。在这些场景中,需要确保只有一个实例对象被创建,否则可能会出现资源的浪费和对象的重复创建等问题。通过实验,熟练使用Java语言实现单例设计模式,理解这种种设计模式的模式动机,掌握模式结构,学习如何使用代码实现这些模式,并学会分析这些模式的使用效果。首先,定义一个 ShoppingCartManager 类,作为购物车管理器,使用单例模式来确保在整个应用程序中只有一个实例对象被创建。单例模式在实际开发中的应用极其广泛。 阅读详情

        单例模式是日常开发中比较常见,使用比较多的设计模式之一,它保证了该类在运行中只有一个实例对象。根据其特性可以用在线程池、上传/下载管理、数据库管理等地方。

        对于有一定开发经验的小伙伴们来说写个线程安全的单例并不是难事,无非是构造私有,提供获取实例的静态方法并保证不同模式下的线程安全,本文对基础不过多赘述,咱们主要讨论一些单例中的细节。

一、单例模式

        讨论细节还是得把咱们常用的单例代码给搬出来

        1.1、饿汉模式:

        饿汉模式的特点是提前创建,直接使用。

public class HungerSingleton {
    private static HungerSingleton INSTANCE = new HungerSingleton();

    private HungerSingleton() {
    }

    public static HungerSingleton getInstance() {
        return INSTANCE;
    }
}

        饿汉模式比较简单,在类初始化的时候就在内存中创建好了实例对象,通过类加载机制保证了线程安全,有个问题是无论有没有使用到该类,其实例对象会一直占用着内存空间。

        1.2、双重锁机制下的懒汉模式

        懒汉模式的特点是随用随创建,当遇到多线程时需要自己来实现线程安全问题。

public class LazySingleton {
    private volatile static LazySingleton INSTANCE;

    private LazySingleton() {
    }

    public static LazySingleton getInstance() {
        if (INSTANCE == null) {
            synchronized (LazySingleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new LazySingleton();
                }
            }
        }
        return INSTANCE;
    }
}

        双重锁机制是在获取实例对象的方法中先进行第一次实例判空,主要是为了如果创建过就直接返回没有必要再次加锁;如果为空则进行加锁再判空,最后创建并返回单例对象。当然还有比较重要的一步是需要在变量前加上volatile关键词修饰,防止指令重排序。

        关于volatile:

        相信很多小伙伴用此模式写单例类的时候会忘记加volatile修饰,或者知道加volatile但是不太清楚加这个关键词的具体作用,在这里我们浅说一下

 volatile是一种轻量级同步机制,有保证可见性、禁止指令重排等特性,咱们在这主要讲一下禁止指令重排。

        我们知道JVM是无法直接运行.java文件的,它需要通过Java编译器编译成.class文件后才能在JVM中运行,在编辑器中我们看.class文件好像跟我们写的代码没啥太大区别,但是在JVM中会把.class翻译成一条条的指令。

        我们在编辑器中可以通过javap -c反编译.class可以看到以下输出:

        学过汇编的小伙伴们可能会感到一股“亲切”,其中每一行就是一条指令,其中比较重要的有new开辟空间、invokespecial初始化、putstatic变量赋值等操作。

        但是编辑器或者CPU为了优化程序的执行性能可能会对指令进行重新排序,比如下图展示:

        可以看出单线程下将赋值和初始化的指令顺序替换,对与第4步的使用并没有影响。

        但是多线程的话就会出现如下情况:

         当线程1执行完赋值操作但是没有初始化的时候,线程2进入判断会发现该成员已经被赋值不为null,进而直接返回使用发现没有初始化,程序的执行就会出现异常。而volatile就是防止此事件发生,让指令禁止排序,顺序执行。

        回归正题可以看出此模式能尽可能的节约空间,但是存在锁也就代表着时间上的消耗。

        那么问题来了有没有既可以懒加载又能不使用锁提高效率的单例模式呢,答案是有的,通过静态内部类的方式创建单例对象

        1.3、静态内部类方式

public class InnerClassSingleton {
    private InnerClassSingleton() {
    }

    public static InnerClassSingleton getInstance() {
        return Singleton.singleton;
    }

    private static class Singleton {
        private static InnerClassSingleton singleton = new InnerClassSingleton();
    }
}

        首先在静态内部类和饿汉模式一样先初始化静态成员变量,通过类加载机制保证了线程安全;由于是内部类所以外部类初始化的时候不会立即加载内部类,内部类不加载那内部的变量自然也不会占用内存,从而保证了延迟加载,这样高效且懒加载的单例方式遍实现了。

        1.4、其他方式

        创建单例还可以通过枚举的方式,不过局限性比较大,这里就不再细说了。

二、单例反制

        上述的单例模式真的能保证实例对象唯一吗?这个当时不是。

        2.1、反射创建

        我们知道通过反射是可以创建新的实例的,如下代码:

try {
    InnerClassSingleton instance = InnerClassSingleton.getInstance();
    Constructor<InnerClassSingleton> constructor = InnerClassSingleton.class.getDeclaredConstructor();
    constructor.setAccessible(true);
    InnerClassSingleton singleton = constructor.newInstance();

    System.out.print(instance == singleton);
} catch (Exception e) {
    e.printStackTrace();
}

        打印结果会发现两个对象并不是一个

        解决方法:

        类可以多次创建,但是静态对象在内存只能有一个引用,并且反射创建也是要走构造器的,那么我们可以在构造器里加入以下判断:

private InnerClassSingleton() {
    if (Singleton.singleton != null) {
        throw new RuntimeException("单例不能有多个实例");
    }
}

        在构造器中判断静态变量是否被赋值,只要检测被赋值代表已经初始化过,那直接可以抛出异常提醒。

        测试结果:

        局限性:相信细心的小伙伴就会发现,这种方式只能用于懒汉模式下的单例创建,确实这样,因为饿汉模式在开始就把单例初始化了,所以无法再进行判断。

        2.2、序列化创建

        序列化在日常开发中也是比较常见,但是用在单例上面那问题就会出来了

        将单例进行序列化和反序列化:

//1、实现Serializable接口
public class InnerClassSingleton implements Serializable {
    /**
     * 防止类更新修改后反序列化失败,保证序列化文件id的统一
     */
    static final long serialVersionUID = 42L;
    //....
}

InnerClassSingleton instance = InnerClassSingleton.getInstance();

//2、序列化生成本地数据文件
try {
    FileOutputStream fosSingleton = new FileOutputStream("singletonInfo");
    ObjectOutputStream oos = new ObjectOutputStream(fosSingleton);
    oos.writeObject(instance);
    oos.close();
} catch (Exception e) {
    e.printStackTrace();
}

        输出的序列化文件:

         通过文件进行反序列化操作:

//3、反序列化
try {
    FileInputStream fisSingleton = new FileInputStream("singletonInfo");
    ObjectInputStream ois = new ObjectInputStream(fisSingleton);
    InnerClassSingleton o = (InnerClassSingleton) ois.readObject();
    ois.close();
    //对比
    System.out.print(instance == o);
} catch (Exception e) {
    e.printStackTrace();
}

        结果测试:

         可以看出通过序列化的方式也能产生不同的对象,并且反序列化创建有独有的机制对象没有走构造器,所以在构造器中判断没有生效。

        解决方法:

        其实如何预防这种情况在序列化注释中已经给出了解决方案:

Classes that need to designate a replacement when an instance of it is read from the stream should implement this special method with the exact signature.

ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;

如果从流中读取的对象需要替换成指定的类的话需要复写readResolve方法,其中修饰符随意,返回Object。

        根据描述我在单例中添加一下代码:

public class InnerClassSingleton implements Serializable {
    /**
     * 防止修改后反序列化失败
     */
    static final long serialVersionUID = 42L;
    //......
    
    /**
    * 复写readResolve,并返回单例对象
    */
    public Object readResolve() throws ObjectStreamException {
        return Singleton.singleton;
    }
}

        原理探究:

        那么为什么复写该方法就会保证实例统一呢,这里我们需要看一下ObjectInputStream的readObject方法内部具体实现原理。

        首先方法内调用到readObject(Class)方法

public final Object readObject()
    throws IOException, ClassNotFoundException {
    return readObject(Object.class);
}

        然后根据返回的obj,调用到readObject0(Class , boolean)方法

private final Object readObject(Class<?> type)
    throws IOException, ClassNotFoundException
{
    //....
    try {
        Object obj = readObject0(type, false);
        //.....
        return obj;
    } finally {
        passHandle = outerHandle;
        if (closed && depth == 0) {
            clear();
        }
    }
}

        根据读取的类型调用到readOrdinaryObject(boolean)方法

private Object readObject0(Class<?> type, boolean unshared) throws IOException {
    boolean oldMode = bin.getBlockDataMode();
    //...
    byte tc;
    while ((tc = bin.peekByte()) == TC_RESET) {
        bin.readByte();
        handleReset();
    }
    //...
    try {
        switch (tc) {
            //...
            case TC_OBJECT:
                if (type == String.class) {
                    throw new ClassCastException("Cannot cast an object to java.lang.String");
                }
                //根据读取类型调用readOrdinaryObject方法。
                return checkResolve(readOrdinaryObject(unshared));
            //...
        }
    }
    //...
}

        在readOrdinaryObject可以看到读取了ReadResolve方法

private Object readOrdinaryObject(boolean unshared)
    throws IOException
{
    //......
    Object obj;
    try {
        //先通过反射创建出新的实例对象
        obj = desc.isInstantiable() ? desc.newInstance() : null;
    } catch (Exception ex) {
        throw new InvalidClassException(desc.forClass().getName(),
                                    "unable to create instance", ex);
    }
    //......
    if (obj != null &&
        handles.lookupException(passHandle) == null &&
        desc.hasReadResolveMethod())
    {
        //反射执行ReadResolve方法,并返回对象,如果没有复习则返回null
        Object rep = desc.invokeReadResolve(obj);
        if (unshared && rep.getClass().isArray()) {
            rep = cloneArray(rep);
        }
        //返回的对象与新创建的对象对比是否一样
        if (rep != obj) {
            // Filter the replacement object
            if (rep != null) {
                if (rep.getClass().isArray()) {
                    filterCheck(rep.getClass(), Array.getLength(rep));
                } else {
                    filterCheck(rep.getClass(), -1);
                }
            }
            //如果不一样则将ReadResolve返回的对象赋值给obj
            handles.setObject(passHandle, obj = rep);
        }
    }
    //最后返回
    return obj;
}

        可以看出在反序列化读取对象的时候,会检测ReadResolve方法的执行,并且根据我们复写方法的返回值来制定反序列化返回的具体对象,如果返回的单例对象就能保证反序列化后对象的统一。

三、总结

        综上可以看出在使用单例的方式比较多种,比较优雅的是通过静态内部类的方式创建,既能保证懒加载又能保证性能,同时为了防止其他方式的创建,可以加入一些必要的反制措施。

        单例的细节就说到这里,如有不足欢迎指出~

Java面试中问单例模式如何回答 单例模式(Singleton Pattern)是一种设计模式,确保某个类在整个应用中只有一个实例,并且提供全局访问点。 阅读详情

相关推荐

Java 单例模式

使用单例模式的本意是 保证类在内存中只能有一个对象 ,单例模式有两种,一个是饿汉式,一个是懒汉式! 假设学校给学姐分配任务:帮助学弟解决问题!

两行代码 踏踏实实de工作 1万+

Java五种单例模式

Java的五种单例模式,大家应该都接触过或者都用过。本篇介绍下Java的五种单例模式,并分析其优缺点,希望给初学者提供一点帮助。

zhaojun的博客 2万+

机器人视觉实战:用OpenCV搞定手眼标定(附完整C++代码)

本文详细介绍了使用OpenCV实现机器人视觉中的手眼标定技术,包括核心算法、工业场景优化及完整C++代码示例。通过解析坐标系转换问题,提供从数据采集到标定验证的全流程解决方案,帮助开发者在复杂工业环境中实现高精度机械臂与视觉系统的协同作业。

weixin_29306571的博客 482

Java之单例模式

在多线程环境下程序运行的结果与单线程环境下程序运行的结果不一样(不达预期)单例模式是一种设计模式(设计模式:就是在特定的场景下,解决问题最优的方式,类似于棋谱),单例:顾名思义,全局只有一个实例对象。初始状态instance=null,外层if判断为true,进入,此时三个线程参与锁竞争,线程1拿到了锁,线程2和线程3处在堵塞状态,线程1内层if判断为true,执行instance的赋值操作,之后释放锁资源,返回赋值之后的对象,线程2拿到了锁资源,内层if判断为false,释放锁资源,返回instance,

qq_64580912的博客 1967

正点原子ATK-LORA-01无线串口代码移植+STM32F103C8T6(标准库)

目录 一、ATK-LORA-01无线串口资料 二、代码移植 1.分析 (1)usart3(也可以是其他的串口)用于接收数据的串口 usart.h (2)time3(也可以是其他的定时器)用于时序的设置 (3)lora.c 三、演示 1.主机(发送方) (1)主机接线 (2)主机代码(发送方) (3)主机实物 插上无线串口通电即可发送​ 2.从机(接收方) (1)从机接线(LORA与主机相同) (2)从机代码(接收方) (3)从机实物 接上TTL和LORA并通电即...

m0_56942354的博客 8968

别再到处搜了!高德地图瓦片URL参数(lang、style、ltype)全解析与实战搭配指南

本文全面解析高德地图瓦片URL参数(lang、style、ltype)的核心逻辑与实战应用,提供18种实用参数组合方案,帮助开发者实现从基础到高阶的定制化地图渲染。涵盖语言控制、地图样式、图层类型等关键参数,并分享WebGIS项目中的优化技巧与常见问题解决方案。

weixin_33724046的博客 117

Java单例模式

5中常见的单例模式,各有优缺点。

weixin_68901096的博客 1782

YOLOv11【第三章:高阶应用与落地篇·第1节】一文搞懂,YOLOv11-Seg 实例分割:Mask 原型生成与系数预测原理解析!

🏆 本文收录于专栏 《YOLOv11实战:从入门到深度优化》。本专栏围绕 YOLOv11 的改进、训练、部署与工程优化 展开,系统梳理并复现当前主流的 YOLOv11 实战案例与优化方案,内容目前已覆盖 分类、检测、分割、追踪、关键点、OBB 检测 等多个方向。

**My Coding Family** 1249

java单例模式--Java单例模式以及6种实现方式

单例模式的主要作用是保证在Java程序中,某个类只有一个实例存在。一些管理器和控制器常被设计成单例模式。

weixin_54620953的博客 2435

理想L9高通QAM8797座舱域控制器全拆解|全网独家复现 硬件架构升级、电源散热优化、多屏低延迟交互、车机系统赋能高端智能座舱落地

随着智能汽车向舱驾一体、全域智能化、多模交互方向迭代,传统单一功能座舱芯片已无法满足多屏高刷渲染、全车AI语音、车内视觉感知、高速车载通信的叠加算力需求。2026款全新理想L9作为旗舰级智能SUV,全面搭载高通新一代旗舰座舱域控制器QAM8797,搭配自研马赫M100 AI芯片、国产车规主控芯片,构建起高性能、高可靠、低延迟的车载中央计算平台。

getusushu的博客 387

【25届数字IC秋招总结】面试经验10——紫光同芯

25届数字ic面试记录——紫光同芯

lalala0635的博客 863

单例模式的那些事

文章目录单例模式单例的特点单例模式的7种写法第一种(懒汉,线程不安全):第二种(懒汉,线程安全):第三种(饿汉):第四种(饿汉,变种):第五种(静态内部类):第六种(枚举):第七种(双重校验锁):单例模式真的能够实现实例的唯一性吗?答案是否定的!如何破坏单例反射序列化和反序列化单元素枚举类型总结 单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型...

VicterTian的博客 443

Deepseek Engram 论文全面解读

以下是对 DeepSeek 与北京大学于联合发布的论文《》(简称Engram 论文)的。

lpfasd123的博客 357

java单例模式、Scala单例模式

单例java的两种单例模式Scala的单例模式 java的两种单例模式 /** * 单例 * * 一个类只能创建一个对象, * 定义的步骤: * 恶汉式: * 1、私有构造器 * 2、提供一个public的static的返回值为本类引用的方法 * 3、为了给第2步中提供实例,创建一个private的s...

Baiyabai的博客 1236

2026年3月GESP真题及题解(C++七级):物流网络

2026年3月GESP真题及题解(C++七级):物流网络

王老师青少年编程 1126

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

java_童年生活二三事

package acmInJava.climbStairs; import java.util.Scanner; /** * Redraiment小时候走路喜欢蹦蹦跳跳,他最喜欢在楼梯上跳来跳去。 但年幼的他一次只能走上一阶或者一下子蹦上两阶。 现在一共有N阶台阶,请你计算一下Redraiment从第0阶到第N阶共有几种走法。 * 输入 * 输入包括多组数据。 每组数据包括一行:N(1≤N≤40)。 输入以0结束。 * <p> * 输出 * 对应每个输入包括一个输出。 为redr

xuchaoxin1375的博客 242

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

如何在Java中实现单例模式?

单例模式是Java编程中常用的设计模式之一,它能够确保一个类只有一个实例,并提供一个全局访问点。通过本文的介绍,相信读者已经掌握了如何在Java中实现单例模式,并了解了其优缺点及适用场景。在实际开发中,可以根据具体需求选择合适的单例模式实现方法。

你好,欢迎来到我的个人技术博客!我是一个还有头发的程序猿,一名热衷于探索编程奥秘的程序员。在这个充满无限可能的数字时代,我致力于通过代码编织梦想,解决问题,不断追求技术的极致。 自从踏上编程之旅以来,我涉足了多个领域,包括但不限于Web开发、移动应用开发 1324

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

java单例模式——详解JAVA单例模式及8种实现方式_单例模式java实现

另一方面,在使用单例对象的时候,要注意单例对象内的实例变量是会被多线程共享的,推荐使用无状态的对象,不会因为多个线程的交替调度而破坏自身状态导致线程安全问题,比如我们常用的VO,DTO等(局部变量是在用户栈中的,而且用户栈本身就是线程私有的内存区域,所以不存在线程安全问题)。缺点:效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。

2501_90256493的博客 855

java单例模式详解

java几种单例模式:1、通过静态内部类实现2、饿汉式3、懒汉式

喵酱 1798

java单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。1、单例类只能有一个实例。2、单例类必须自己创建自己的唯一实例。

2401_86544677的博客 736

java 单例模式

之前的日积月累专栏就是为了温故而知新,查漏补缺写的,现在的新专栏: 有趣的java数据结构,我会放一些有意思的数据结构和重要的知识点在里面 目录单例模式自我理解标准概念懒汉式和饿汉式的区别 单例模式 自我理解 单例模式就是做一个 :不断去拿同一个事物,在做同一件事的小程序。这个同一个事物要求很苛刻。 举个例子:我要我今天刚买的那一只小猫,它两岁,我起名为橘喵,我只想带着它,而不是别的猫,哪怕这只猫和我的橘喵外貌,年龄都一模一样,但我能知道,这已经不是属于我的,那只我想要的猫了。 实例代码: 创建一个 猫 的

qq_49290616的博客 757

java手写一个单例模式

目录什么是单例模式?使用单例模式的目的?懒汉式恶汉式懒汉式 双重锁 什么是单例模式? 单例类只能有一个实例 单例类必须自己创建自己的唯一实例 单例类必须给所有其他对象提供这一实例 使用单例模式的目的? 单例模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在 懒汉式 线程不安全单例模式 public class Singleton { private stati...

weixin_44906271的博客 2280

异常的二三事

Java中虽然已经内置了丰富的异常类但是我们实际场景中可能还有一些情况需要我们对异常类进行扩展创建符合我们实际情况的异常例如我们实现一个用户登陆功能if (!// TODO处理用户名错误if (!// TODO处理密码错误登陆成功");此时我们在处理用户名密码错误的时候可能就需要抛出两种异常我们可以基于已有的异常类进行扩展继承),创建和我们业务相关的异常类比特科技此时我们的login代码可以改成try {if (!用户名错误");if (

cjh_yyds的博客 1016
上一篇: 【转载】解决 IllegalStateException: Can not perform this action after onSaveInstanceState
下一篇: 一份详细的Handler原理解析
Code_dh
博客等级 码龄8年 58粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值