zoukankan      html  css  js  c++  java
  • java锁的释义

    1 各种锁的释义

    1.1 死锁

    死锁是指两个线程同时占用两个资源,又在彼此等待对方释放锁资源

    import java.util.concurrent.TimeUnit;
    
    public class LockExample {
        public static void main(String[] args) {
            deadLock(); // 死锁
        }
        /**
         * 死锁
         */
        private static void deadLock() {
            Object lock1 = new Object();
            Object lock2 = new Object();
            // 线程一拥有 lock1 试图获取 lock2
            new Thread(() -> {
                synchronized (lock1) {
                    System.out.println("获取 lock1 成功");
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 试图获取锁 lock2
                    synchronized (lock2) {
                        System.out.println(Thread.currentThread().getName());
                    }
                }
            }).start();
            // 线程二拥有 lock2 试图获取 lock1
            new Thread(() -> {
                synchronized (lock2) {
                    System.out.println("获取 lock2 成功");
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 试图获取锁 lock1
                    synchronized (lock1) {
                        System.out.println(Thread.currentThread().getName());
                    }
                }
            }).start();
        }
    }
    

    1.2 悲观锁

    悲观锁指的是数据对外界的修改采取保守策略,它认为线程很容易会把数据修改掉,因此在整个数据被修改的过程中都会采取锁定状态,直到一个线程使用完,其他线程才可以继续使用。
    可以看出被 synchronized 修饰的代码块,在执行之前先使用 monitorenter 指令加锁,然后在执行结束之后再使用 monitorexit 指令释放锁资源,在整个执行期间此代码都是锁定的状态,这就是典型悲观锁的实现流程。

    1.3 乐观锁

    乐观锁认为一般情况下数据在修改时不会出现冲突,所以在数据访问之前不会加锁,只是在数据提交更改时,才会对数据进行检测。
    Java 中的乐观锁大部分都是通过 CAS(Compare And Swap,比较并交换)操作实现的,CAS 是一个多线程同步的原子指令,CAS 操作包含三个重要的信息,即内存位置、预期原值和新值。如果内存位置的值和预期的原值相等的话,那么就可以把该位置的值更新为新值,否则不做任何修改。
    ABA问题

    1.4 可重入锁

    可重入锁也叫递归锁,指的是同一个线程,如果外面的函数拥有此锁之后,内层的函数也可以继续获取该锁。在 Java 语言中 ReentrantLock 和 synchronized 都是可重入锁。
    可重入锁的实现原理,是在锁内部存储了一个线程标识,用于判断当前的锁属于哪个线程,并且锁的内部维护了一个计数器,当锁空闲时此计数器的值为 0,当被线程占用和重入时分别加 1,当锁被释放时计数器减 1,直到减到 0 时表示此锁为空闲状

    1.5 共享锁和独占锁

    只能被单线程持有的锁叫独占锁,可以被多线程持有的锁叫共享锁。
    独占锁指的是在任何时候最多只能有一个线程持有该锁,比如 synchronized 就是独占锁,而 ReadWriteLock 读写锁允许同一时间内有多个线程进行读操作,它就属于共享锁。
    独占锁可以理解为悲观锁,当每次访问资源时都要加上互斥锁,而共享锁可以理解为乐观锁,它放宽了加锁的条件,允许多线程同时访问该资源。

  • 相关阅读:
    python操作MySQL数据库
    用python监控您的window服务
    关于position定位中的几个注意点
    filter 滤镜
    git使用心得
    :after,:before,content
    outline和border
    《css揭秘》之背景与边框
    css权威指南学习笔记--第6章
    浅谈setTimeout和setInterval
  • 原文地址:https://www.cnblogs.com/ysit/p/13227999.html
Copyright © 2011-2022 走看看