0基础学java之Day29(单例模式、死锁)

单例模式

理解:在整个项目中,该类的实例只能有一个

1.饿汉式

  • 优点:线程安全

  • 缺点:浪费资源

复制代码
public class A {
​
    private static A a = new A();
    
    private A(){}
    
    public static A getInstance(){
        return a;
    }
    
    public static void method(){
        System.out.println("好好学习,天天向上");
    }
​
    
public static void main(String[] args) {
        
//      A a1 = A.getInstance();
//      A a2 = A.getInstance();
//      
//      System.out.println(a1 == a2);//true
        
        A.method();//哪怕调用方法也会创建对象开辟空间
    }

2.饱汉式

  • 优点:节约资源

  • 缺点:线程不安全

复制代码
public class A {
​
    private static A a;
    
    private A(){}
    
    public static A getInstance(){
        if(a == null){
            a = new A();
        }
        return a;
    }
    
    public static void method(){
        System.out.println("好好学习,天天向上");
    }
}
​
​
public static void main(String[] args) {
        
        A a1 = A.getInstance();
        A a2 = A.getInstance();
        System.out.println(a1 == a2);//true
        
//      A.method();
    }

3.双重校验

  • 优点:节约资源、线程安全
复制代码
public class A {
    
    //创建一个对象的步骤:A a = new A();
    //1.创建对象空间,分配地址 -- new --> 0x001
    //2.调用构造方法,初始化成员变量
    //3.将对象地址赋值给引用
    //注意:创建对象的步骤有可能是1、2、3,也有可能是1、3、2
    //注意:使用volatile修饰的对象被创建的步骤必须是1、2、3
​
    private static volatile A a;
    
    private A(){}
    
    public static A getInstance(){
        
        if(a == null){
            synchronized (A.class) {
                if(a == null){
                    a = new A();
                }
            }
        }
        return a;
    }
    
    public static void method(){
        System.out.println("好好学习,天天向上");
    }
​
    
public static void main(String[] args) {
        
        A a1 = A.getInstance();
        A a2 = A.getInstance();
        
        System.out.println(a1 == a2);//true
        
//      A.method();
    }    

死锁

  • 注意:死锁不一定每次都出现

  • 经验:尽可能避免锁嵌套

复制代码
public class Test01 {
​
    public static void main(String[] args) {
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (KuaiZi.a) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (KuaiZi.b) {
                        System.out.println("哲学家1发现了");
                    }
                }
            }
        }).start();
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (KuaiZi.b) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (KuaiZi.a) {
                        System.out.println("哲学家2发现了");
                    }
                }
            }
        }).start();
        
        
    }
}
class KuaiZi{
    
    public static Object a = new Object();
    public static Object b = new Object();
    
}
相关推荐
沙白猿12 分钟前
【TJXT】Day3
java·开发语言
百锦再19 分钟前
Java的TCP和UDP实现详解
java·spring boot·tcp/ip·struts·spring cloud·udp·kafka
毕设源码-朱学姐21 分钟前
【开题答辩全过程】以 高校实验室管理系统为例,包含答辩的问题和答案
java
A_B_C_Q25 分钟前
StringBuilder 与 StringBuffer的区别
java·前端
用户9083246027329 分钟前
Spring AI 1.1.2 集成 MCP(Model Context Protocol)实战:以 Tavily 搜索为例
java·后端
罗超驿34 分钟前
JavaSE高频答疑:内部类同名变量访问全解 + Comparable与Comparator核心区别
java·开发语言·idea
夕除1 小时前
js--23
java
无尽的沉默1 小时前
Thymeleaf 表达式
java·开发语言·前端
无尽的沉默2 小时前
Spring Boot 整合 Thymeleaf 模板引擎
java·前端·spring boot
Java后端的Ai之路2 小时前
【JDK】-JDK 11 新特性内容整理(很全面)
java·开发语言·后端·jdk