当前位置: 首页 > news >正文

建设网站网页打不开写一个网站需要什么技术

建设网站网页打不开,写一个网站需要什么技术,搜索引擎外部链接优化,制作网页的三大技术是什么第16讲 | synchronized底层如何实现#xff1f;什么是锁的升级、降级#xff1f; 我在上一讲对比和分析了 synchronized 和 ReentrantLock#xff0c;算是专栏进入并发编程阶段的热身#xff0c;相信你已经对线程安全#xff0c;以及如何使用基本的同步机制有了基础#…第16讲 | synchronized底层如何实现什么是锁的升级、降级 我在上一讲对比和分析了 synchronized 和 ReentrantLock算是专栏进入并发编程阶段的热身相信你已经对线程安全以及如何使用基本的同步机制有了基础今天我们将深入了解 synchronize 底层机制分析其他锁实现和应用场景。 今天我要问你的问题是 synchronized 底层如何实现什么是锁的升级、降级 典型回答 在回答这个问题前先简单复习一下上一讲的知识点。synchronized 代码块是由一对儿 monitorenter/monitorexit 指令实现的Monitor 对象是同步的基本实现单元。 在 Java 6 之前Monitor 的实现完全是依靠操作系统内部的互斥锁因为需要进行用户态到内核态的切换所以同步操作是一个无差别的重量级操作。 现代的OracleJDK 中JVM 对此进行了大刀阔斧地改进提供了三种不同的 Monitor 实现也就是常说的三种不同的锁偏斜锁Biased Locking、轻量级锁和重量级锁大大改进了其性能。 所谓锁的升级、降级就是 JVM 优化 synchronized 运行的机制当 JVM 检测到不同的竞争状况时会自动切换到适合的锁实现这种切换就是锁的升级、降级。 当没有竞争出现时默认会使用偏斜锁。JVM 会利用 CAS 操作compare and swap在对象头上的 Mark Word 部分设置线程 ID以表示这个对象偏向于当前线程所以并不涉及真正的互斥锁。这样做的假设是基于在很多应用场景中大部分对象生命周期中最多会被一个线程锁定使用偏斜锁可以降低无竞争开销。 如果有另外的线程试图锁定某个已经被偏斜过的对象JVM 就需要撤销revoke偏斜锁并切换到轻量级锁实现。轻量级锁依赖 CAS 操作 Mark Word 来试图获取锁如果重试成功就使用普通的轻量级锁否则进一步升级为重量级锁。 我注意到有的观点认为 Java 不会进行锁降级。实际上据我所知锁降级确实是会发生的当 JVM 进入安全点SafePoint的时候会检查是否有闲置的 Monitor然后试图进行降级。 考点分析 今天的问题主要是考察你对 Java 内置锁实现的掌握也是并发的经典题目。我在前面给出的典型回答涵盖了一些基本概念。如果基础不牢有些概念理解起来就比较晦涩我建议还是尽量理解和掌握即使有不懂的也不用担心在后续学习中还会逐步加深认识。 我个人认为能够基础性地理解这些概念和机制其实对于大多数并发编程已经足够了毕竟大部分工程师未必会进行更底层、更基础的研发很多时候解决的是知道与否真正的提高还要靠实践踩坑。 后面我会进一步分析 从源码层面稍微展开一些 synchronized 的底层实现并补充一些上面答案中欠缺的细节有同学反馈这部分容易被问到。如果你对 Java 底层源码有兴趣但还没有找到入手点这里可以成为一个切入点。 理解并发包中 java.util.concurrent.lock 提供的其他锁实现毕竟 Java 可不是只有 ReentrantLock 一种显式的锁类型我会结合代码分析其使用。 知识扩展 我在上一讲提到过 synchronized 是 JVM 内部的 Intrinsic Lock所以偏斜锁、轻量级锁、重量级锁的代码实现并不在核心类库部分而是在 JVM 的代码中。 Java 代码运行可能是解释模式也可能是编译模式如果不记得请复习专栏第 1 讲所以对应的同步逻辑实现也会分散在不同模块下比如解释器版本就是http://hg.openjdk.java.net/jdk/jdk/file/6659a8f57d78/src/hotspot/share/interpreter/interpreterRuntime.cpp 为了简化便于理解我这里会专注于通用的基类实现 http://hg.openjdk.java.net/jdk/jdk/file/6659a8f57d78/src/hotspot/share/runtime/ 另外请注意链接指向的是最新 JDK 代码库所以可能某些实现与历史版本有所不同。 首先synchronized 的行为是 JVM runtime 的一部分所以我们需要先找到 Runtime 相关的功能实现。通过在代码中查询类似“monitor_enter”或“Monitor Enter”很直观的就可以定位到 sharedRuntime.cpp/hpp它是解释器和编译器运行时的基类。(http://hg.openjdk.java.net/jdk/jdk/file/6659a8f57d78/src/hotspot/share/runtime/sharedRuntime.cpp) synchronizer.cpp/hppJVM 同步相关的各种基础逻辑。(https://hg.openjdk.java.net/jdk/jdk/file/896e80158d35/src/hotspot/share/runtime/synchronizer.cpp) 在 sharedRuntime.cpp 中下面代码体现了 synchronized 的主要逻辑。 Handle h_obj(THREAD, obj);if (UseBiasedLocking) {// Retry fast entry if bias is revoked to avoid unnecessary inflationObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);} else {ObjectSynchronizer::slow_enter(h_obj, lock, CHECK);}其实现可以简单进行分解 UseBiasedLocking 是一个检查因为在 JVM 启动时我们可以指定是否开启偏斜锁。 偏斜锁并不适合所有应用场景撤销操作revoke是比较重的行为只有当存在较多不会真正竞争的 synchronized 块儿时才能体现出明显改善。实践中对于偏斜锁的一直是有争议的有人甚至认为当你需要大量使用并发类库时往往意味着你不需要偏斜锁。从具体选择来看我还是建议需要在实践中进行测试根据结果再决定是否使用。 还有一方面是偏斜锁会延缓 JIT 预热的进程所以很多性能测试中会显式地关闭偏斜锁命令如下 -XX:-UseBiasedLocking fast_enter 是我们熟悉的完整锁获取路径slow_enter 则是绕过偏斜锁直接进入轻量级锁获取逻辑。 那么 fast_enter 是如何实现的呢同样是通过在代码库搜索我们可以定位到 synchronizer.cpp。 类似 fast_enter 这种实现解释器或者动态编译器都是拷贝这段基础逻辑所以如果我们修改这部分逻辑要保证一致性。这部分代码是非常敏感的微小的问题都可能导致死锁或者正确性问题。 void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock,bool attempt_rebias, TRAPS) {if (UseBiasedLocking) {if (!SafepointSynchronize::is_at_safepoint()) {BiasedLocking::Condition cond BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD);if (cond BiasedLocking::BIAS_REVOKED_AND_REBIASED) {return;}} else {assert(!attempt_rebias, can not rebias toward VM thread);BiasedLocking::revoke_at_safepoint(obj);}assert(!obj-mark()-has_bias_pattern(), biases should be revoked by now);}slow_enter(obj, lock, THREAD); } 我来分析下这段逻辑实现 biasedLocking(http://hg.openjdk.java.net/jdk/jdk/file/6659a8f57d78/src/hotspot/share/runtime/biasedLocking.cpp)定义了偏斜锁相关操作revoke_and_rebias 是获取偏斜锁的入口方法revoke_at_safepoint 则定义了当检测到安全点时的处理逻辑。 如果获取偏斜锁失败则进入 slow_enter。 这个方法里面同样检查是否开启了偏斜锁但是从代码路径来看其实如果关闭了偏斜锁是不会进入这个方法的所以算是个额外的保障性检查吧。 另外如果你仔细查看synchronizer.cpp(https://hg.openjdk.java.net/jdk/jdk/file/896e80158d35/src/hotspot/share/runtime/synchronizer.cpp)里会发现不仅仅是 synchronized 的逻辑包括从本地代码也就是 JNI触发的 Monitor 动作全都可以在里面找到jni_enter/jni_exit。 关于biasedLocking(http://hg.openjdk.java.net/jdk/jdk/file/6659a8f57d78/src/hotspot/share/runtime/biasedLocking.cpp)的更多细节我就不展开了明白它是通过 CAS 设置 Mark Word 就完全够用了对象头中 Mark Word 的结构可以参考下图 顺着锁升降级的过程分析下去偏斜锁到轻量级锁的过程是如何实现的呢 我们来看看 slow_enter 到底做了什么。 void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {markOop mark obj-mark();if (mark-is_neutral()) {// 将目前的Mark Word复制到Displaced Header上lock-set_displaced_header(mark);// 利用CAS设置对象的Mark Wordif (mark obj()-cas_set_mark((markOop) lock, mark)) {TEVENT(slow_enter: release stacklock);return;}// 检查存在竞争} else if (mark-has_locker() THREAD-is_lock_owned((address)mark-locker())) {// 清除lock-set_displaced_header(NULL);return;}// 重置Displaced Headerlock-set_displaced_header(markOopDesc::unused_mark());ObjectSynchronizer::inflate(THREAD,obj(),inflate_cause_monitor_enter)-enter(THREAD); } 请结合我在代码中添加的注释来理解如何从试图获取轻量级锁逐步进入锁膨胀的过程。你可以发现这个处理逻辑和我在这一讲最初介绍的过程是十分吻合的。 设置 Displaced Header然后利用 cas_set_mark 设置对象 Mark Word如果成功就成功获取轻量级锁。 否则 Displaced Header然后进入锁膨胀阶段具体实现在 inflate 方法中。 今天就不介绍膨胀的细节了我这里提供了源代码分析的思路和样例考虑到应用实践再进一步增加源代码解读意义不大有兴趣的同学可以参考我提供的synchronizer.cpp链接例如 deflate_idle_monitors 是分析锁降级逻辑的入口这部分行为还在进行持续改进因为其逻辑是在安全点内运行处理不当可能拖长 JVM 停顿STWstop-the-world的时间。 fast_exit 或者 slow_exit 是对应的锁释放逻辑。 前面分析了 synchronized 的底层实现理解起来有一定难度下面我们来看一些相对轻松的内容。 我在上一讲对比了 synchronized 和 ReentrantLockJava 核心类库中还有其他一些特别的锁类型具体请参考下面的图。 你可能注意到了这些锁竟然不都是实现了 Lock 接口ReadWriteLock 是一个单独的接口它通常是代表了一对儿锁分别对应只读和写操作标准类库中提供了再入版本的读写锁实现ReentrantReadWriteLock对应的语义和 ReentrantLock 比较相似。 StampedLock 竟然也是个单独的类型从类图结构可以看出它是不支持再入性的语义的也就是它不是以持有锁的线程为单位。 为什么我们需要读写锁ReadWriteLock等其他锁呢 这是因为虽然 ReentrantLock 和 synchronized 简单实用但是行为上有一定局限性通俗点说就是“太霸道”要么不占要么独占。实际应用场景中有的时候不需要大量竞争的写操作而是以并发读取为主如何进一步优化并发操作的粒度呢 Java 并发包提供的读写锁等扩展了锁的能力它所基于的原理是多个读操作是不需要互斥的因为读操作并不会更改数据所以不存在互相干扰。而写操作则会导致并发一致性的问题所以写线程之间、读写线程之间需要精心设计的互斥逻辑。 下面是一个基于读写锁实现的数据结构当数据量较大并发读多、并发写少的时候能够比纯同步版本凸显出优势。 public class RWSample {private final MapString, String m new TreeMap();private final ReentrantReadWriteLock rwl new ReentrantReadWriteLock();private final Lock r rwl.readLock();private final Lock w rwl.writeLock();public String get(String key) {r.lock();System.out.println(读锁锁定);try {return m.get(key);} finally {r.unlock();}}public String put(String key, String entry) {w.lock();System.out.println(写锁锁定);try {return m.put(key, entry);} finally {w.unlock();}}// …} 在运行过程中如果读锁试图锁定时写锁是被某个线程持有读锁将无法获得而只好等待对方操作结束这样就可以自动保证不会读取到有争议的数据。 读写锁看起来比 synchronized 的粒度似乎细一些但在实际应用中其表现也并不尽如人意主要还是因为相对比较大的开销。 所以JDK 在后期引入了 StampedLock在提供类似读写锁的同时还支持优化读模式。优化读基于假设大多数情况下读操作并不会和写操作冲突其逻辑是先试着读然后通过 validate 方法确认是否进入了写模式如果没有进入就成功避免了开销如果进入则尝试获取读锁。请参考我下面的样例代码。 public class StampedSample {private final StampedLock sl new StampedLock();void mutate() {long stamp sl.writeLock();try {write();} finally {sl.unlockWrite(stamp);}}Data access() {long stamp sl.tryOptimisticRead();Data data read();if (!sl.validate(stamp)) {stamp sl.readLock();try {data read();} finally {sl.unlockRead(stamp);}}return data;}// … } 注意这里的 writeLock 和 unLockWrite 一定要保证成对调用。 你可能很好奇这些显式锁的实现机制Java 并发包内的各种同步工具不仅仅是各种 Lock其他的如Semaphore、CountDownLatch甚至是早期的FutureTask等都是基于一种AQS框架。 今天我全面分析了 synchronized 相关实现和内部运行机制简单介绍了并发包中提供的其他显式锁并结合样例代码介绍了其使用方法希望对你有所帮助。 一课一练 关于今天我们讨论的你做到心中有数了吗思考一个问题你知道“自旋锁”是做什么的吗它的使用场景是什么 请你在留言区写写你对这个问题的思考我会选出经过认真思考的留言送给你一份学习奖励礼券欢迎你与我一起讨论。 证成对调用。 你可能很好奇这些显式锁的实现机制Java 并发包内的各种同步工具不仅仅是各种 Lock其他的如Semaphore、CountDownLatch甚至是早期的FutureTask等都是基于一种AQS框架。 今天我全面分析了 synchronized 相关实现和内部运行机制简单介绍了并发包中提供的其他显式锁并结合样例代码介绍了其使用方法希望对你有所帮助。 一课一练 关于今天我们讨论的你做到心中有数了吗思考一个问题你知道“自旋锁”是做什么的吗它的使用场景是什么 请你在留言区写写你对这个问题的思考我会选出经过认真思考的留言送给你一份学习奖励礼券欢迎你与我一起讨论。 你的朋友是不是也在准备面试呢你可以“请朋友读”把今天的题目分享给好友或许你能帮到他。
http://www.hkea.cn/news/14480228/

相关文章:

  • 中国建设银行信用卡官方网站wordpress 高级字段
  • 重庆快速网站推广做英文版网站
  • 曾经做网站网站代理wordpress后端响应慢
  • 做推送的网站有哪些html5 网站开发 适配
  • 福州建设网站linux增加网站
  • 海外社交网站开发百度学术官网入口网页版
  • 怎样在百度上作网站推广iis 二级网站 发布
  • seo建站公司怎么制作微信链接网页
  • gta5线下买房网站建设沈阳 网站开发
  • html网站标签wordpress建站吧
  • 网站建设 微信开发上海网页设计公司济南兴田德润团队怎么样
  • se 网站优化网站服务器 同步备份
  • 网站建设指导合同手机wap网站是什么
  • 淘宝客的网站怎么做的网站建设论文开题报告范文
  • 肥料网站建设 中企动力百度站长平台网站体检
  • 做决定的网站网站搭建协议
  • 所有网上购物的网站创意设计海报
  • 什么网站做的最好礼品类网站建设策划方案
  • 长春网站长春网络推广建设南平建设集集团网站
  • 国内惯性导航seo关键词库
  • 北京自适应网站建设山东省建设部网站官网
  • 高端网站建设公司哪家公司好网站建设考虑哪些因素
  • 建立网站服务器搜狗短网址生成
  • 戴尔网站建设国际最新局势最新消息
  • 内网做网站需要空间吗望野什么意思
  • 北京网站制作平台沈阳网站制作公司和服务器
  • 网站建设 事业单位 安全重庆沙坪坝网站建设
  • 中国摄影网站十大排名河南郑州暴雨
  • 中国品牌设计公司个人网站seo
  • 北京市住房与城乡建设厅网站软件开发设计文档示例