zoukankan      html  css  js  c++  java
  • 重入, 中断, 公平, 读写锁

    重入, 中断, 公平, 读写锁

    标签(空格分隔): 操作系统


    可重入锁 / 不可重入锁

    可重入锁

    Wikipedia: 若一个程序或子程序可以" 在任意时刻被打断然后操作系统调度之行另一端代码, 这段代码又调用了该子程序而不会出错 " 则称其为可重入锁. 即当该子程序正在运行时, 执行线程可以再次进入并执行它, 仍然获得符合设计时的预期结果. 与多线程并发执行的线程安全不同, 可重入强调对单个线程执行时重新进入同一个子程序仍然是安全的.

    某个线程试图获取一个已经由他自己持有的锁. 这个请求可以成功, 那么此时的锁就是可重入锁, 重入锁的这种机制也说明了它是以 "线程" 为粒度获取锁, 而不是以"调用"为粒度.

    重入锁一个常见的实现方式是, 为每一个锁关联一个持有者和持有计数值, 当计数值为0时, 这个锁会被认为没有被任何线程持有, 当线程请求一个未被持有的锁的时候, JVM会把这个锁给这个线程, 并记下这个锁的持有者, 同时计数器值置为1, 如果同一个线程再次获取这个锁, 计数值递增一. 当线程同步代码块时, 计数值将递减一, 当为0时, 锁被释放. 常见的重入锁有SynchronizedReenTrantLock

    不可重入锁

    不可重入锁和可重入锁相反, 就是同一个线程多次请求同一把锁就会出现死锁. 可以看到父类和子类的MethodA方法的synchronized持有的锁都是SuperSynObj.class, 他们两个持有同一把锁, 如果Synchronized不是可重入锁的话, 会在代码的的注释出 出现死锁的状况.

    class SuperSynObj {
        public synchronized void methodA() {
            synchronized (SuperSynObj.class) {
                System.out.println("Super class running");
            }
        }
    }
    
    class SynObj extends SuperSynObj {
        @Override
        public void methodA() {
            synchronized (SuperSynObj.class) {
                System.out.println("methodA");
    
                try {
                    super.methodA(); // 不是重入锁将在 此处 出现死锁.
                    Thread.sleep(5000);
                    super.methodA();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    class Dog {
        public static void main(String[] args) {
            new SynObj().methodA();
        }
    }
    

    现在模拟一个不可重入的自旋锁.

  • 相关阅读:
    Spring 学习——Spring IOC概念
    Oracle使用——Oracle表空间处理
    Spring 学习——Spring框架结构、概念
    Java错误——The hierarchy of the type is inconsistent错误
    Git教程
    git 常用操作
    "use strict"; 的正确使用
    react学习笔记(二)React表单详解
    chrome 添加有用扩展程序
    react学习笔记(一)
  • 原文地址:https://www.cnblogs.com/A-FM/p/12673893.html
Copyright © 2011-2022 走看看