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();
    
}
相关推荐
咕白m6251 小时前
Java 实现 Excel 转 HTML:完整示例
java
RealPluto2 小时前
Spring AOP 失效排查
java·spring
码路飞2 小时前
热榜全是 OpenClaw,但我用 50 行 Python 就造了个桌面 AI Agent 🤖
java·javascript
Nyarlathotep01132 小时前
LinkedList源码分析
java·后端
用户8307196840822 小时前
Java 告别繁琐数据统计代码!MySQL 8 窗口函数真香
java·sql·mysql
带刺的坐椅3 小时前
SolonCode v0.0.20 发布 - 编程智能体(新增子代理和浏览器能力)
java·ai·agent·solon·solon-ai·claude-code·openclaw
会员源码网4 小时前
数字格式化陷阱:如何优雅处理 NumberFormatException
java
孔明click335 小时前
Sa-Token v1.45.0 发布 🚀,正式支持 Spring Boot 4、新增 Jackson3/Snack4 插件适配
java·sa-token·开源·springboot·登录·权限认证
程序猿阿越5 小时前
Kafka4源码(二)创建Topic
java·后端·源码阅读
悟空码字5 小时前
Spring Boot 整合 MongoDB 最佳实践:CRUD、分页、事务、索引全覆盖
java·spring boot·后端