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();
    
}
相关推荐
缺点内向3 小时前
Java:创建、读取或更新 Excel 文档
java·excel
带刺的坐椅3 小时前
Solon v3.4.7, v3.5.6, v3.6.1 发布(国产优秀应用开发框架)
java·spring·solon
四谎真好看5 小时前
Java 黑马程序员学习笔记(进阶篇18)
java·笔记·学习·学习笔记
桦说编程5 小时前
深入解析CompletableFuture源码实现(2)———双源输入
java·后端·源码
java_t_t5 小时前
ZIP工具类
java·zip
lang201509285 小时前
Spring Boot优雅关闭全解析
java·spring boot·后端
pengzhuofan6 小时前
第10章 Maven
java·maven
百锦再7 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
刘一说7 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
壹佰大多7 小时前
【spring如何扫描一个路径下被注解修饰的类】
java·后端·spring