第十三章 显示锁

  Java 5.0 提供的新的加锁机制:当内置加锁机制不适合时 , 作为一种可选择的高级功能

  一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

13.1 Lock 与 ReentrantLock

  Lock 中实现的必须提供与内置锁相同的内存可见

性语义, 但在加锁语义,调度算法,顺序保证和性能特性方面有所不同.

13.1.1 轮询锁和定时锁

  在内置锁中, 解决死锁的唯一方法是 重新启动程序. 防止死锁的唯一方法是 构造程序时避免出现不一致的锁顺序(互相等待).

  避免死锁的方法 :

    通过定时或轮询的方式去获取锁 : 如果不能获得所有需要的锁, 则释放所有已经获得的锁. 然后重新尝试获取所有锁.

  内置锁在请求锁之后 ,此操作无法取消.

13.1.2 可中断的锁获取操作

  不可中断的阻塞机制使得任务的取消变得复杂.

  tryLock() 方法可实现定时的和可中断的所获取操作.

13.1.3 非块结构的加锁

  内置锁中,  进入synchronize 代码块自动加锁, 执行完代码块自动释放锁. 锁的获取与释放在同一代码块中. 简化了程序的分析, 但缺少一定的灵活性.

  显示锁中, 加锁操作和释放锁操作可以不在同一个代码块中 , 提高的锁的灵活性 . 但是也带来一定的危险性(比如忘了释放锁)

  通过降低锁的粒度可以提高代码的可伸缩性.

  锁分段技术: 在基于散列的容器中实现不同的散列链, 以便使用不同的锁.

  可采用类似的原则降低链表中锁的粒度 .

  连锁式加锁或者锁耦合 : 对链表的每个节点加锁, 操作此节点时必须拥有此节点的锁, 只有获取到下个节点的锁时才释放上个节点的锁.

13.2 锁的性能

  Java 5.0 中, 多线程环境下 显示锁的性能优于内置锁.

  Java 6.0 中, 内置锁使用类似与显示锁的算法进行优化, 两者的性能 基本接近.

13.3 公平性

  ReentrantLock 在构造时可选择使用公平锁和非公平锁.

  • 公平锁中, 若有线程持有锁或有其他线程在队列中等待这个锁, 则新发出请求这个锁的线程将被放入队列中.
  • 非公平锁中, 只有当锁被某个线程持有时, 新发出请求锁的线程才会被放入队列中.
  • 公平锁由于线程的挂起和恢复的开销(线程从挂起状态到恢复运行状态需要一定的时间)而极大的降低性能..
  • 非公平时可能在某个线程在其它线程争抢锁之前就已经锁的使用,这样并不影响其它线程的使用,提高了性能

  选择 : 当持有锁的时间相对较长或者请求锁的平均时间间隔较长时可选择使用 公平锁

13.4 synchronize 和 ReetrantLock

  • 仅当内置锁不满足需求时才考虑使用显示锁.
  • 内置锁在线程转储中能给出在哪些调用帧中获得了哪些锁 , 并能够检测和识别发生死锁的线程. 而显示锁不可以
  • synchronize 是JVM的内置属性, 优化方面更加方便. 推荐使用内置锁.

13.5 读---写锁(ReadWriteLock)

  • 一个资源科被多个读操作访问, 或者被一个写操作访问. 但两者不能同时进行.
  • 非公平模式 : 连续竞争的非公平锁可能无限期地推迟一个或多个 reader 或 writer 线程,但吞吐量通常要高于公平锁。
  • 公平模式 : 当释放当前保持的锁时,可以为等待时间最长的单个 writer 线程分配写入锁,如果有一组等待时间大于所有正在等待的 writer 线程 的 reader 线程,将为该组分配写入锁(防止公平模式下写线程饥饿)
  • 重入还允许从写入锁降级为读取锁,其实现方式是:先获取写入锁,然后获取读取锁,最后释放写入锁。但是,从读取锁升级到写入锁是不可能的

原文地址:https://www.cnblogs.com/virgosnail/p/9446523.html

时间: 2024-07-29 15:59:36

第十三章 显示锁的相关文章

javascript高级程序设计 第十三章--事件

javascript高级程序设计 第十三章--事件js与HTML的交互就是通过事件实现的,事件就是文档或浏览器窗口中发生的一些特定的交互瞬间. 事件流:事件流描述的是从页面中接收事件的顺序,IE的是事件冒泡流,Netscape的是事件捕获流,这个两个是完全相反的事件流概念. 事件冒泡:由最具体的元素接收,然后逐级向上传播到更高级的节点,即事件沿DOM树向上传播,直到document对象. 事件捕获:不大具体的节点应该更早接收到事件,相当于沿DOM节点树向下级传播直到事件的实际目标,在浏览器中,是

CSS3秘笈复习:十三章&十四章&十五章&十六章&十七章

第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮动元素.关键字:left.right或both. (2).浮动外围元素:让包含浮动元素的<div>也浮动.选择这种方法一定要在浮动容器后面的任何元素中添加一个clear属性,确保浮动元素落到容器的下方. (3).利用overflow : hidden.另一种常见的方法是在外围的样式中添加以下属性:

JavaScript高级程序设计:第十三章

第十三章 一.理解事件流 事件流描述的是从页面中接收事件的顺序. 1.事件冒泡 IE的事件流叫做事件冒泡,即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点.以下面的HTML页面为例: <!DOCTYPE html> <html> <head> <title>Event Bubling Example</title> </head> <body> <div id="myDiv"&g

HTML与CSS入门——第十三章  使用框架

知识点: 1.建立框架集的方法 2.在框架和窗口之间链接的方法 3.使用内联框架的方法 13.1 什么是框架: 框架是浏览器窗口中的一个矩形区域,每个框架显示的是一个完整的页面. 作者不建议使用框架,原因: 1.框架与Web的基础概念冲突 /*什么概念?*/ 2.框架化的网站的打印部分非常困难. 3.如果框架爱缺乏合适的编码,或者有合适的编码但是被用于邪恶的目的,用户可能在框架化的网站中无法看到框架外部的内容. /*不明白……*/ 4.框架已经从html5标准中移除…… 但是iframe依旧存在

第十三章 进程、线程类的实现

                                        第十三章   进程.线程类的实现         多线程是指在一个进程内可以同时运行多个任务,每个任务由一个单独的线程来完成.线程是进程运行的基本单位,一个进程中可以同时运行多个线程.如果程序被设置为多线程方式,可以提高程序运行的效率和处理速度. 多个线程共用一个进程的资源:进程的调度.切换是在10ms的"时钟滴答"定时中断程序里进行.如果一个线程获得CPU,那么在下一个Tick到来前:是不可能被切换出去的

第十三章 虚函数

第十三章 虚函数 1.  指向对象的指针 常用 不常用????????? 2.  虚函数 virtual  体现虚函数的 多态性(动态联编) 存储不同对象的指针调用不同类的函数 3.  拳击游戏 4.  继承是否可以实现多态性 继承无法实现多态,要想实现多态就要在基类加virtual 5.  在编译时的静态联编 6.  在运行时的静态联编 7.  在运行时的动态联编 动态联编体现了多态性 所以一定要有virtual 而且要用指针或者别名 否则不能实现 8.  在编译时的动态联编 9.  三种调用

第五——十三章的作业

第五章 1.团队模式和团队的开发模式有什么关系? 团队模式指团队的分工模式,团队内部的结构,团队开发模式指团队开发的流程及步骤 2.如果你领头开展一个全新的项目,你要怎么选择“合适”的团队模式? 根据团队的能力和项目的结构,选择合适的团队模式.如果大家都比较自觉,且其中有一人能力较强,就会选择主治医师模式.如果项目比较复杂且每个人都有自己熟悉的开发领域,会选择功能团队模式.如果项目在不同方向和领域都有任务,就会选交响乐团模式.如果是开放式项目,可能会选择爵士乐模式.如果开发的人非常多,会选择官僚

Gradle 1.12用户指南翻译——第二十三章. Java 插件

其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://github.com/msdx/gradledoc/tree/1.12. 直接浏览双语版的文档请访问: http://gradledoc.qiniudn.com/1.12/userguide/userguide.html. 另外,Android 手机用户可通过我写的一个程序浏览文档,带缓存功能的,兼容

第十三章——表和索引分区(2)——使用拆分删除和加载大数据

原文:第十三章--表和索引分区(2)--使用拆分删除和加载大数据 前言: 很多时候需要对大数据量进行归档或者删除,并周期性加载大数据量到一个大表中,现在来做个简单的例子,你经常需要删除大数据量表中的大量数据.同时,你想加载大量数据到这个表中,当表中数据有数十亿时,这个操作可能消耗几个小时,但是如果你的表有分区,那么执行起来会很有效. 本文将模拟删除一个季度的数据,并加载整个季度到现有表,其中使用了拆分(splitting).合并(merging)和切换分区(switching). 假设我们需要存