• 写一个死锁的例子、写一个单例模式(饿汉式和懒汉式)和双重校验锁


    一、使用synchronized 和 Thread.sleep()写一个简单的死锁

    package com.线程.死锁;
    
    public class DeadLockSleep {
        public static void main(String[] args) {
            Object A = new Object();
            Object B = new Object();
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (A) {
                        System.out.println("t1 getLock A");
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        synchronized (B) {
                            System.out.println("t1 getLock B");
                        }
                    }
                    System.out.println("t1 end");
                }
            });
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (B) {
                        System.out.println("t2 getLock B");
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        synchronized (A) {
                            System.out.println("t2 getLock A");
                        }
                    }
                    System.out.println("t2 end");
                }
            });
            t1.start();
            t2.start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    运行如下:

    在这里插入图片描述

    二、饿汉式

    饿汉式在类加载时就实例化了,使用时直接调用 getInstance() 方法。这个模式为线程安全的,在多线程并发模式下不会重复实例化对象。

    • 优点: 效率高
    • 缺点: 对象实例化过早,浪费内存资源
    class Singleton1 {
        private static Singleton1 instance = new Singleton1();
        private Singleton1() {}
        public static Singleton1 getInstance() {
            return instance;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、懒汉式

    这种模式没有在加载时实例化对象,而是在调用getInstance() 方法时实例化对象,使用懒汉式是为了避免过早的实例化,减少内存资源浪费。

    • 优点:第一次调用才初始化,避免内存浪费。
    • 缺点: 只适合单线程,线程不安全
    class Singleton2 {
        private static Singleton2 instance;
        private Singleton2() {}
        public static Singleton2 getInstance() {
            if (instance == null) {
                instance = new Singleton2();
            }
            return instance;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    四、双重校验锁

    • 使用volitile关键字防止最里面的instance = new Singleton();出现指令重排

    instance = new Singleton();大致有三个步骤:

    • 在堆中开辟对象所需空间,在堆中分配内存地址
    • 根据类加载的初始化顺序进行初始化
    • 将堆中的内存地址返回给栈中的引用变量
    class Singleton {
        private static volatile Singleton instance;
        private Singleton() {}
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    C++11 原子变量
    腾讯云 AI 绘画:文生图、图生图、图审图 快速入门
    通过mxGraph在ARMxy边缘计算网关上实现工业物联网
    [每周一更]-(第63期):Linux-nsenter命令使用说明
    变身“毒”苹果?全球首个 DMP 漏洞,仅 A14、M1 等苹果芯片独有
    Aria2NG连接aria2-pro提示认证失败的处理办法
    自动驾驶之入门目录【转】
    Java-访问控制
    JS利用循环解决的一些问题
    学生管理系统(半成品)
  • 原文地址:https://blog.csdn.net/m0_46378271/article/details/126491405