「Java Web」Java中的单例模式:懒汉与饿汉

本文介绍了Java中的两种单例模式——饿汉模式和懒汉模式。饿汉模式在类加载时即创建单例,适合多线程环境,而懒汉模式则在首次使用时创建单例,适用于单线程。文中详细分析了两种模式的实现方式、内存分配以及线程安全问题,并给出了代码示例和测试结果。
摘要由CSDN通过智能技术生成

前言:
在我们开发项目的时候,需要考虑项目的资源占用情况,减少项目的资源占用,提高执行效率。那么单例模式则是必不可少的一种开发模式。

何为单例模式
单例模式顾名思义就只在内存中存在一个对象,用这个对象来满足方法的调用。这样减少了new的步骤,也就减少了资源的占用。

1.饿汉模式
一般在多线程的情况下,这种单例模式用的比较多,用哪种单例模式还的看自己项目情况。这种模式一旦项目编译启动了就开始创建对象。这种模式适用于多线程。

package 单例模式;

/*
饿汉模式 (项目编译好就加载)
只有一个对象,
只能在使用该类的时候创建,
这样才能保证在内存中只存在一个对象。
 */

public class HungrySingleTon {
    //在创建一个类的时候直接创建
    private  final  static HungrySingleTon instance=new HungrySingleTon();

    HungrySingleTon(){

    }

    //然后返回一个内存地址
    public static HungrySingleTon getInstance(){
        return  HungrySingleTon.instance;
        //JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样能保证instance只被创建一次
        //防止多线程并发导致创建多个实例
    }
}

饿汉模式与普通模式所分配的内存
请添加图片描述

2.懒汉模式
这种模式适用于单线程的项目,用于使用时加载类的情况。但这种模式不安全。当用多线程的时候,可能会由于并发导致创建多个实例对象出来。

  //在创建的时候来判断有没有创建实例,没创建新创建一个
    //这种方式不安全,再多线程中 会实例出多个对象出来
    public  static  LazySingleTon getInstance(){
        if (lazySingleTon==null){
            lazySingleTon=new LazySingleTon();
        }
        return lazySingleTon;
    }

优化一下 用synchronized同步加锁即可解决
但这样虽然避免了多线程中由于执行速度过快导致的多个实例被创建,但是每次调用这种getinstance的时候都会给实例对象同步加锁,这样会降低程序执行的效率。

    //同步加锁后就能保证线程安全,但效率就变低了(每次调用getInstance 都要同步上锁)
    public static synchronized LazySingleTon  getInstance(){
        if (lazySingleTon==null){
            lazySingleTon=new LazySingleTon();
        }
        return lazySingleTon;
    }

最后,用代码块来提高效率并提高安全性
在每次调用方法getInstance的时候,先判断对象是否被创建。再决定加不加锁创建对象。

      //效率高且比较安全的一种懒汉单例模式
    public static LazySingleTon getInstance(){
        if (lazySingleTon==null){
            //使用代码块提高效率
            lazySingleTon = new LazySingleTon();
            synchronized (lazySingleTon){ }
        }
        return  lazySingleTon;
    }

测试类

package 单例模式;

public class test {


    public static void main(String[] args) {

        HungrySingleTon hungrySingleTon =new HungrySingleTon();
        HungrySingleTon hungrySingleTon1 =new HungrySingleTon();
        commonMode commonMode=new commonMode();
        commonMode commonMode1=new commonMode();
        LazySingleTon lazySingleTon=new LazySingleTon();
        LazySingleTon lazySingleTon1=new LazySingleTon();
        HungrySingleTon test1= hungrySingleTon1.getInstance();
        LazySingleTon lazy1=lazySingleTon.getInstance();
        System.out.println(test1.toString());
        System.out.println(commonMode.toString());
        System.out.println(lazy1.toString());
        new Thread(new Runnable() {
            @Override
            public void run() {
                HungrySingleTon test2= hungrySingleTon1.getInstance();
                LazySingleTon lazy2=lazySingleTon1.getInstance();
                System.out.println(test2.toString());
                System.out.println(commonMode1.toString());
                System.out.println(lazy2.toString());
            }
        }).start();
    }
}

运行结果
请添加图片描述

以上内容由自己整理思路发布,如有错误欢迎指正 😊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0xdF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值