首页 > 其他分享 >为什么要使用单例模式?

为什么要使用单例模式?

时间:2023-03-27 23:47:30浏览次数:39  
标签:为什么 log ... 模式 单例 new Logger public

单例设计模式 (Singleton Design Pattern) 理解起来非常简单.一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式.简称单例模式.

实战案例一: 处理资源访问冲突

一个例子,自定义实现了一个往文件中打印日志的Logger类.具体实现代码如下:

点击查看代码
public class Logger {
  private FileWriter writer;
  
  public Logger() {
    File file = new File("/Users/wangzheng/log.txt");
    writer = new FileWriter(file, true); //true表示追加写入
  }
  
  public void log(String message) {
    writer.write(mesasge);
  }
}

// Logger类的应用示例:
public class UserController {
  private Logger logger = new Logger();
  
  public void login(String username, String password) {
    // ...省略业务逻辑代码...
    logger.log(username + " logined!");
  }
}

public class OrderController {
  private Logger logger = new Logger();
  
  public void create(OrderVo order) {
    // ...省略业务逻辑代码...
    logger.log("Created an order: " + order.toString());
  }
}

在上面的代码中,我们注意到,所有的日志都写入到同一个文件/Users/wangzheng/log.txt中。在UserController和OrderController中,我们分别创建两个Logger对象。在Web容器的Servlet多线程环境下,如果两个Servlet线程同时分别执行login()和create()两个函数,并且同时写日志到log.txt文件中,那就有可能存在日志信息互相覆盖的情况。

为什么会出现互相覆盖呢?我们可以这么类比着理解。在多线程环境下,如果两个线程同时给同一个共享变量加1,因为共享变量是竞争资源,所以,共享变量最后的结果有可能并不是加了2,而是只加了1。同理,这里的log.txt文件也是竞争资源,两个线程同时往里面写数据,就有可能存在互相覆盖的情况。

我们将Logger设计成一个单例类,程序中只允许创建一个Logger对象,所有的线程共享使用的这一个Logger对象,共享一个FileWriter对象,而FileWriter本身是对象级别线程安全的,也就避免了多线程情况下写日志会互相覆盖的问题。

按照这个设计思路,我们实现了Logger单例类,具体代码如下:

点击查看代码
public class Logger {
  private FileWriter writer;
  private static final Logger instance = new Logger();

  private Logger() {
    File file = new File("/Users/wangzheng/log.txt");
    writer = new FileWriter(file, true); //true表示追加写入
  }
  
  public static Logger getInstance() {
    return instance;
  }
  
  public void log(String message) {
    writer.write(mesasge);
  }
}

// Logger类的应用示例:
public class UserController {
  public void login(String username, String password) {
    // ...省略业务逻辑代码...
    Logger.getInstance().log(username + " logined!");
  }
}

public class OrderController {  
  public void create(OrderVo order) {
    // ...省略业务逻辑代码...
    Logger.getInstance().log("Created a order: " + order.toString());
  }
}

标签:为什么,log,...,模式,单例,new,Logger,public
From: https://www.cnblogs.com/tianjinlong/p/17255848.html

相关文章

  • 为什么我会持续写面经
    title:为什么我会持续写面经date:2023-03-2722:19:07categories:-感悟及认知tags:-感悟及认知为什么我会持续写面经?从我去年投出第一份简历,经历第一场面试,到......
  • 我为什么推荐Nuxt3
    我为什么推荐Nuxt3?大家好,我今天想和你们分享一个非常棒的前端框架——Nuxt3。自从我接触了Nuxt3,我发现它在前端开发领域具有很多优点。我想逐一向你们介绍Nuxt3的优势,并向......
  • 为什么软件开发周期总是预估的2~3倍?
      软件开发周期总是预估的2~3倍是一个普遍存在的现象,主要有以下原因:  预估不足:软件开发需要涉及多个环节,如需求分析、设计、编码、测试等,每个环节都需要时间和资......
  • 哥终于知道了苹果为什么发布的是iPhone 4S而非iPhone 5
    当得知上周苹果发布的是iPhone4S而不是iPhone5时,哥顿感失望。哥当时就想,假如苹果发布的是iPhone5而不是iPhone4S的话,销量一定会比现在更好。如果苹果推出一款全新的iP......
  • (二十四)享元模式
    1.概述享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象。2.示例Flyweight类,它是所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状......
  • 为什么三星Galaxy S II比iPhone大?
    还记得三星GalaxySII广告吗?广告中,果粉将拿iPhone和GalaxySII进行对比,发小iPhone比自己的手机小,果粉对三星用户一脸羡慕,知道为什么GalaxySII会比iPhone大吗?对于3.5......
  • 前端-工厂模式
    工厂模式大体分为三类:简单工厂模式、工厂方法模式、抽象工厂模式。三者之间的关系,也是渐进式的,抽象化的范围也是越来越高。简单工厂模式:根据不同条件去生成不同对象(......
  • 为什么要执行产值冲减的原因--因为系统设计的逻辑问题--产值冲减、工程结算、收入台账
    1.系统设计时间逻辑的问题1.PM系统的时间逻辑flowchartLRA["产值冲减(时间A:统计月份)"]-->B["工程结算(时间B:结算月份)"]-->C["收入台账(时间C:统计月份)"]2.问题的发生......
  • Android 架构设计(一):设计模式分析
    现有Android主流设计模式有哪些?1:无架构     -很多人把无架构定为MVC,这边深海要纠正一下,无架构!=MVC 2:MVC      Model -数据模型/数据来源。View......
  • 小米为什么不怕iPhone降价?
    地球人都知道,国外有个乔布斯,国内有个雷布斯,国外有iPhone,国内有小米。小米在国内的影响力是有目共睹的,虽然在国际影响力跟iPhone无法媲美,但还是引起了巨大关注和好奇,虽然有......