当前位置: 首页 > article >正文

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();
    
}

http://www.kler.cn/a/442280.html

相关文章:

  • 算法与数据结构——复杂度
  • 【开源免费】基于SpringBoot+Vue.JS欢迪迈手机商城(JAVA毕业设计)
  • LDD3学习7--硬件接口I/O端口(以short为例)
  • 【postgres】sqlite格式如何导入postgres数据库
  • Go语言简洁框架目录和高效的快发框架设计
  • Linux操作命令之云计算基础命令
  • MySQL 的锁
  • 如何更新项目中的 npm 或 Yarn 依赖包至最新版本
  • 编写工具模块
  • MyBatis的面试题以及详细解答
  • Java学习教程,从入门到精通,Java ConcurrentHashMap语法知识点及案例代码(63)
  • 探秘 JSON:数据交互的轻盈使者
  • 学技术学英文:代码中的锁:悲观锁和乐观锁
  • docker 安装 mongo 命令
  • 使用DPO技术对大模型Qwen2.5进行微调
  • YOLOv9-0.1部分代码阅读笔记-augmentations.py
  • List接口
  • HTML5 MathML
  • 【mysql】如何解决主从架构从库延迟问题
  • MybatisPlus介绍与应用
  • 泷羽sec学习打卡-brupsuite8伪造IP和爬虫审计
  • CTF_1
  • STM32-笔记4-按键点亮led
  • Jsckson @JsonValue 注解
  • springcloud打成jar包运行在centos7
  • 使用html2canvas库对可滚动的dom节点导出全量的图片