Day01-Idea插件+单例模式
一、IDEA插件
1.1 Apifox Helper
作用:将Controller中的方法上传到Apifox并转换为相应的接口文档。
安装和使用步骤:
1、在idea的插件库搜索Apifox Helper并Install安装。
2、安装完成后,在idea的设置中,会多出一个ApifoxHelper设置的界面。并需要我们去配置API访问令牌。
3、Apifox访问令牌需要从客户端的账号设置-》新建令牌中获取。获取完成后将获取到的令牌填入idea的令牌配置当中即可。
4、使用:将光标放到要生成接口文档的controller中,右键,则可以看到upload to Apifox选项。
5、执行完后,需要输入要导出的Apifox上的项目id。这时需要去Apifox的项目概述中去获取。
6、此时则可以看到Apifox中已多出一组接口文档。
1.2 Translation
简介:TranslationPlugin 是一个基于 IDEA 的翻译插件。它集成了谷歌翻译、微软翻译、DeepL 翻译、有道翻译、百度翻译等众多翻译引擎,在 IDEA 内可随时对想要翻译的文本、代码注释、代码文档等进行翻译。
安装和使用步骤:
1、在idea的插件库搜索Translation并Install安装。
2、安装完成后在设置中搜索translation则可以看到Translation的设置界面。
3、注册翻译服务,并获取其应用程序ID和应用程序密钥。
推荐注册百度翻译,可翻译词汇量多,其他翻译服务需要收费。
百度翻译平台地址:https://fanyi-api.baidu.com/。
在百度翻译平台选择【通用文本翻译】服务并开通,则可以看到对应的APPID和密钥。
4、配置完百度翻译的APPID和密钥之后则可以在idea中选择文本右键选择Translate Selection进行翻译了。
二、设计模式-单例模式
单例模式(Singleton Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
何时使用:当您想控制实例数目,节省系统资源的时候。
使用举例:回收站、WEB计数器
在我们的windows桌面上,我们打开了一个回收站,当我们试图再次打开一个新的回收站时,Windows系统并不会为你弹出一个新的回收站窗口。也就是说在整个系统运行的过程中,系统只维护一个回收站的实例。这就是一个典型的单例模式运用。
网站的计数器,一般也是采用单例模式实现,如果你存在多个计数器,每一个用户的访问都刷新计数器的值,这样的话你的实计数的值是难以同步的。
实现:
我们将创建一个 SingleObject 类。SingleObject类有它的私有构造函数和本身的一个静态实例。
SingleObject类提供了一个静态方法,供外界获取它的静态实例。SingletonPatternDemo 类使用 SingleObject 类来获取 SingleObject对象。
创建单例步骤如下:
1)类的内部声明或创建对象
2)构造器私有化(防止new)
3)向外暴露一个公共方法(getInstance)
步骤一:
public class SingleObject {
//类加载的时候,创建SingleObject的一个对象
private static SingleObject instance = new SingleObject();
//让构造函数为 private,这样该类就不会被实例化
private SingleObject(){}
//获取唯一可用的对象
public static SingleObject getInstance(){
return instance;
}
public void showMessage(){
System.out.println("Hello World!");
}
}
步骤二:
public class SingletonApplication {
public static void main(String[] args) {
//不合法的构造函数
//编译时错误:构造函数 SingleObject() 是不可见的
//SingleObject object = new SingleObject();
//获取唯一可用的对象
SingleObject object = SingleObject.getInstance();
//显示消息
object.showMessage();
}
}
输出:Hello World!
1、懒汉式(线程不安全)
是否 Lazy 初始化:是
是否多线程安全:否
理解:懒汉模式就是加载类的时候只声明变量,不new对象,后面用到的时候再new对象,然后把对象赋给该变量。
描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
缺点:在多个线程同时调用getInstance
方法时,由于方法没有加锁,多个线程可能会创建多个对象,导致实例的数据不同步。
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton (){}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
2、懒汉式(线程安全)
是否 Lazy 初始化:是
是否多线程安全:是
描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,大部分情况下不需要同步。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。对整个 getInstance() 方法加锁,这样做代价很大,因为,只有当第一次调用 getInstance() 时才需要同步创建对象,创建之后再次调用 getInstance() 时就只是简单的返回成员变量,而这里是无需同步的,所以没必要对整个方法加锁。
public class LazySingletonSafe {
private static LazySingletonSafe instance;
private LazySingletonSafe (){}
public static synchronized LazySingletonSafe getInstance() {
if (instance == null) {
instance = new LazySingletonSafe();
}
return instance;
}
}
3、饿汉式(线程安全)
是否 Lazy 初始化:否
是否多线程安全:是
理解:饿汉模式就是加载类的时候直接new一个对象,后面直接用即可。
描述:饿汉模式是在类加载时将其实例化的,在饿汉模式下,在Class Loader
完成后该类的实例便已经存在于JVM中了,即,在getInstance
方法第一次被调用前该实例已经存在了,因此是线程安全的。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
public class HungrySingleton {
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton (){}
public static HungrySingleton getInstance() {
return instance;
}
}
懒汉式和饿汉式的区别:
饿汉模式是在类加载时将其实例化的,在饿汉模式下,在Class Loader完成后该类的实例便已经存在于JVM中了,即,在getInstance方法第一次被调用前该实例已经存在了,new对象的操作不在getInstance方法内。
而懒汉模式在类中只是定义了变量但是并未实例化,实例化的过程是在获取单例对象的方法中实现的,即,在getInstance方法第一次被调用后该实例才会被创建,new对象的操作在getInstance方法内。
4、双检锁/双重校验锁(DCL,即 double-checked locking)
是否 Lazy 初始化:是
是否多线程安全:是
描述:懒汉模式虽然节省了内存,但是却需要使用锁来保证单例,getInstance() 的性能对应用程序很关键,因此,双重校验锁就是懒汉模式的升级版本。
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
代码解释:
加Volatile是为了禁止指定重排。
在 synchronized 代码块之外再加一个 if 判断,这样,当 INSTANCE 已经存在时,线程先判断不为null,然后直接返回,避免了进入 synchronized 同步代码块。第二个if是懒汉式原理的校验。
写在文末:
1、synchronized方法控制对对象的访问,每个对象对应一把锁,每个synchronized方法都必须获得调用该方法的对象的锁才能执行,否则线程会阻塞,方法一旦执行,就会独占该锁,知道该方法返回才释放锁,后面被阻塞的线程才能获得这个锁,继续执行。
作用:把出现线程安全问题的核心代码给上锁。
原理:每次只能一个线程进入,执行完毕后自动解锁,其他线程才可以进来执行。
2、 同步块:synchronized(obj){}
obj称之为同步监视器
obj可以是任何对象.但是推荐使用共享资源作为同步监视器
第一个线程访问,锁定同步监视器,执行其中代码
第二个线程访问,发现同步监视器被锁定,无法访问
第一个线程访问完毕,解锁同步监视器
第二个线程访问,发现同步监视器没有锁,然后锁定并访问
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)