zoukankan      html  css  js  c++  java
  • 锁的了解

    10.锁
    悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现
    乐观锁
    总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

    乐观锁的缺点
    ---1 ABA 问题是乐观锁一个常见的问题
    ---2 循环时间长开销大
    ---3 只能保证一个共享变量的原子操作

    总结::
    MyISAM 采用表级锁(table-level locking)。
    InnoDB 支持行级锁(row-level locking)和表级锁,默认为行级锁


    死锁:
    概念:所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外 力作用,它们都将无法再向前推进
    产生死锁的原因:
    1.竞争资源
    ---产生死锁中的竞争资源之一指的是竞争不可剥夺资源(例如:系统中只有一台打印机,可供进程P1使 用,假定P1已占用了打印机,若P2继续要求打印机打印将阻塞)
    ---产生死锁中的竞争资源另外一种资源指的是竞争临时资源(临时资源包括硬件中断、信号、消息、缓 冲区内的消息等),通常消息通信顺序进行不当,则会产生死锁
    2. 进程间推进顺序非法
    ---若P1保持了资源R1,P2保持了资源R2,系统处于不安全状态,因为这两个进程再向前推进,便可能发生 死锁
    ---例如,当P1运行到P1:Request(R2)时,将因R2已被P2占用而阻塞;当P2运行到P2:Request(R1) 时,也将因R1已被P1占用而阻塞,于是发生进程死锁

    死锁产生的4个必要条件:
    互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
    请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
    不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
    环路等待条件:在发生死锁时,必然存在一个进程--资源的环形链。

    预防死锁:
    资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)
    只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)
    可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
    资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反
    (破坏环路等待条件)

    避免死锁:
    预防死锁的几种策略,会严重地损害系统性能。因此在避免死锁时,要施加较弱的限制,从而获得 较满意的系 统性能。由于在避免死锁的策略中,允许进程动态地申请资源。因而,系统在进行资源分配之前预先计算资源 分配的安全性。若此次分配不会导致系统进入不安全的状态,则将资源分配给进程;否则,进程等待。其中最 具有代表性的避免死锁算法是银行家算法。

    ---银行家算法:首先需要定义状态和安全状态的概念。系统的状态是当前给进程分配的资源情况。因此,状态包含两个向量Resource(系统中每种资源的总量)和Available(未分配给进程的每种资源的总量)及两个矩阵Claim(表示进程对资源的需求)和Allocation(表示当前分配给进程的资源)。安全状态是指至少有一个资源分配序列不会导致死锁。当进程请求一组资源时,假设同意该请求,从而改变了系统的状态,然后确定其结果是否还处于安全状态。如果是,同意这个请求;如果不是,阻塞该进程知道同意该请求后系统状态仍然是安全的。
    解除死锁:
    当发现有进程死锁后,便应立即把它从死锁状态中解脱出来,常采用的方法有:
    剥夺资源:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态;
    撤消进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态.消除为 止;所谓代价是指优先级、运行代价、进程的重要性和价值等。
    死锁检测:
    Jstack命令:
    jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。 Jstack工具可以用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。
    JConsole工具:
    Jconsole是JDK自带的监控工具,在JDK/bin目录下可以找到。它用于连接正在运行的本地或者远程的JVM,对运行在Java应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。而且本身占用的服务器内存很小,甚至可以说几乎不消耗

  • 相关阅读:
    netty+springboot+oracle+protobuf 搭建客户端服务端
    netty框架学习记录
    sql查询替换逗号拼接的字符窜
    Node的webpack打包的核心思想就是单页面富应用(SPA)
    Javascript 中的 CJS, AMD, UMD 和 ESM是什么
    springboot读取jar中resource下的文件
    zmq模块的理解和使用二
    问问题
    Java解析kml文件
    练习本
  • 原文地址:https://www.cnblogs.com/slfeng/p/11154541.html
Copyright © 2011-2022 走看看