前言
一、单例模式的介绍
二、单例模式的 8 种实现方式(懒汉式要注意线程安全问题)
1、饿汉式(静态常量)
代码示例
package tanchishell.SJMS;
public class SingletonTest01 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
//饿汉式(静态变量)
class Singleton {
//1. 构造器私有化, 外部能 new
private Singleton() {
}
//2.本类内部创建对象实例
private final static Singleton instance = new Singleton();
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
return instance;
}
}
输出
true
instance.hashCode=460141958
instance2.hashCode=460141958
优缺点:可能会造成内存的浪费,但也只能浪费内存
2、饿汉式(静态代码块)
代码示例
package tanchishell.SJMS;
public class SingletonTest01 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
//饿汉式(静态变量)
class Singleton {
//1. 构造器私有化, 外部能 new
private Singleton() {
}
//2.本类内部创建对象实例
// private final static Singleton instance = new Singleton();
private static Singleton instance;
static {
//使用静态代码块,不再使用 final 修饰为常量
instance = new Singleton();
}
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
return instance;
}
}
输出
true
instance.hashCode=460141958
instance2.hashCode=460141958
3、懒汉式(线程不安全)不推荐
代码示例
package tanchishell.SJMS;
public class SingletonTest01 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
//饿汉式(静态变量)
class Singleton {
//1. 构造器私有化, 外部能 new
private Singleton() {
}
//2.本类内部创建对象实例
private static Singleton instance;
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
输出
true
instance.hashCode=460141958
instance2.hashCode=460141958
缺点:多线程不安全
4、懒汉式(线程安全,同步方法)添加 synchronized 关键字
package tanchishell.SJMS;
public class SingletonTest01 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
//饿汉式(静态变量)
class Singleton {
//1. 构造器私有化, 外部能 new
private Singleton() {
}
//2.本类内部创建对象实例
private static Singleton instance;
//3. 提供一个公有的静态方法,返回实例对象
/** 添加 synchronized 关键字保证线程安全 */
public static synchronized Singleton getInstance() {
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
输出
true
instance.hashCode=460141958
instance2.hashCode=460141958
缺点效率太低
5、懒汉式(同步代码块)不能使用,解决不了线程安全问题
6、懒汉式(双重检查加 volatile关键字)推荐使用
package tanchishell.SJMS;
public class SingletonTest01 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
//饿汉式(静态变量)
class Singleton {
//1. 构造器私有化, 外部能 new
private Singleton() {
}
//2.本类内部创建对象实例,添加 volatile 保证有序性和可见性
private static volatile Singleton instance;
//3. 提供一个公有的静态方法,返回实例对象
/** 双重检查加 volatile 关键字 */
public static Singleton getInstance() {
if(instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
输出
true
instance.hashCode=460141958
instance2.hashCode=460141958
7、静态内部类
在类加载时,静态内部类没有调用是不会进行类加载的,当被调用时才会被加载,而且只加载一次,加载时线程安全
package tanchishell.SJMS;
public class SingletonTest01 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
//饿汉式(静态变量)
class Singleton {
//1. 构造器私有化, 外部能 new
private Singleton() {
}
//提供一个静态内部类,根据JVM底层机制保证线程安全
private static class SingletonInstance{
private static final Singleton INSTANCE = new Singleton();
}
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
Singleton instance = SingletonInstance.INSTANCE;
return instance;
}
}
输出
true
instance.hashCode=460141958
instance2.hashCode=460141958
优缺点
8、使用枚举实现单例懒加载
package tanchishell.SJMS;
public class SingletonTest01 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.INSTANCE;
Singleton instance2 = Singleton.INSTANCE;
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
instance.method();
}
}
enum Singleton{
INSTANCE;
public void method(){
System.out.println("hello,world");
}
}
输出
true
instance.hashCode=460141958
instance2.hashCode=460141958
hello,world
三、JDKの RunTime 类使用的是单例模式
文章来源:https://www.toymoban.com/news/detail-420094.html
四、单例模式注意事项和细节说明
文章来源地址https://www.toymoban.com/news/detail-420094.html
到了这里,关于第四章 单例模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!