摘要: http://cmsblogs.com/?p=2122 阅读全文
posted @ 2018-04-12 12:34 Call_Me_Tiger_Fu 阅读(228) 评论(0) 推荐(0) 编辑
摘要: CAS,Compare And Swap,即比较并交换。Doug lea大神在同步组件中大量使用CAS技术鬼斧神工地实现了Java多线程的并发操作。整个AQS同步组件、Atomic原子类操作等等都是以CAS实现的,甚至ConcurrentHashMap在1.8的版本中也调整为了CAS+Synchro 阅读全文
posted @ 2018-04-12 12:33 Call_Me_Tiger_Fu 阅读(212) 评论(0) 推荐(0) 编辑
摘要: 此篇博客所有源码均来自JDK 1.8 在没有Lock之前,我们使用synchronized来控制同步,配合Object的wait()、notify()系列方法可以实现等待/通知模式。在Java SE5后,Java提供了Lock接口,相对于Synchronized而言,Lock提供了条件Conditi 阅读全文
posted @ 2018-04-12 11:44 Call_Me_Tiger_Fu 阅读(225) 评论(0) 推荐(0) 编辑
摘要: 此篇博客所有源码均来自JDK 1.8 重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少。然而读服务不存在数据竞争问题,如果一个线程在读时禁止其他线程读势必会导致性能降低。所以就提供了读写锁。 读写 阅读全文
posted @ 2018-04-12 11:43 Call_Me_Tiger_Fu 阅读(170) 评论(0) 推荐(0) 编辑
摘要: 此篇博客所有源码均来自JDK 1.8 ReentrantLock,可重入锁,是一种递归无阻塞的同步机制。它可以等同于synchronized的使用,但是ReentrantLock提供了比synchronized更强大、灵活的锁机制,可以减少死锁发生的概率。 API介绍如下: 一个可重入的互斥锁定 L 阅读全文
posted @ 2018-04-12 11:42 Call_Me_Tiger_Fu 阅读(138) 评论(0) 推荐(0) 编辑
摘要: 此篇博客所有源码均来自JDK 1.8 在线程获取同步状态时如果获取失败,则加入CLH同步队列,通过通过自旋的方式不断获取同步状态,但是在自旋的过程中则需要判断当前线程是否需要阻塞,其主要方法在acquireQueued(): 通过这段代码我们可以看到,在获取同步状态失败后,线程并不是立马进行阻塞,需 阅读全文
posted @ 2018-04-12 11:40 Call_Me_Tiger_Fu 阅读(679) 评论(0) 推荐(1) 编辑
摘要: 此篇博客所有源码均来自JDK 1.8 在前面提到过,AQS是构建Java同步组件的基础,我们期待它能够成为实现大部分同步需求的基础。AQS的设计模式采用的模板方法模式,子类通过继承的方式,实现它的抽象方法来管理同步状态,对于子类而言它并没有太多的活要做,AQS提供了大量的模板方法来实现同步,主要是分 阅读全文
posted @ 2018-04-12 11:39 Call_Me_Tiger_Fu 阅读(226) 评论(0) 推荐(0) 编辑
摘要: 此篇博客所有源码均来自JDK 1.8 在上篇博客【死磕Java并发】—–J.U.C之AQS:AQS简介中提到了AQS内部维护着一个FIFO队列,该队列就是CLH同步队列。 CLH同步队列是一个FIFO双向队列,AQS依赖它来完成同步状态的管理,当前线程如果获取同步状态失败时,AQS则会将当前线程已经 阅读全文
posted @ 2018-04-12 11:38 Call_Me_Tiger_Fu 阅读(204) 评论(0) 推荐(0) 编辑
摘要: 经过四篇博客阐述,我相信各位对Java内存模型有了最基本认识了,下面LZ就做一个比较简单的总结。 总结 JMM规定了线程的工作内存和主内存的交互关系,以及线程之间的可见性和程序的执行顺序。一方面,要为程序员提供足够强的内存可见性保证;另一方面,对编译器和处理器的限制要尽可能地放松。JMM对程序员屏蔽 阅读全文
posted @ 2018-04-12 11:37 Call_Me_Tiger_Fu 阅读(146) 评论(0) 推荐(0) 编辑
摘要: DCL,即Double Check Lock,中卫双重检查锁定。其实DCL很多人在单例模式中用过,LZ面试人的时候也要他们写过,但是有很多人都会写错。他们为什么会写错呢?其错误根源在哪里?有什么解决方案?下面就随LZ一起来分析 问题分析 我们先看单例模式里面的懒汉式: 我们都知道这种写法是错误的,因 阅读全文
posted @ 2018-04-12 11:36 Call_Me_Tiger_Fu 阅读(254) 评论(0) 推荐(0) 编辑
摘要: 前篇博客【死磕Java并发】—–深入分析volatile的实现原理 中已经阐述了volatile的特性了: 下面LZ就通过happens-before原则和volatile的内存语义两个方向介绍volatile。 volatile与happens-before 在这篇博客【死磕Java并发】—–Ja 阅读全文
posted @ 2018-04-12 11:35 Call_Me_Tiger_Fu 阅读(205) 评论(0) 推荐(0) 编辑
摘要: 在上篇博客(【死磕Java并发】—–深入分析volatile的实现原理)LZ提到过由于存在线程本地内存和主内存的原因,再加上重排序,会导致多线程环境下存在可见性的问题。那么我们正确使用同步、锁的情况下,线程A修改了变量a何时对线程B可见? 我们无法就所有场景来规定某个线程修改的变量何时对其他线程可见 阅读全文
posted @ 2018-04-12 11:34 Call_Me_Tiger_Fu 阅读(106) 评论(0) 推荐(0) 编辑
摘要: 在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件: 如果看过LZ上篇博客的就会知道,其实这两点可以归结于一点:无法通过happens-before原则推导出来的,JMM允许任意的排序。 as-if-serial语 阅读全文
posted @ 2018-04-12 11:34 Call_Me_Tiger_Fu 阅读(435) 评论(0) 推荐(0) 编辑
摘要: 通过前面一章我们了解了synchronized是一个重量级的锁,虽然JVM对它做了很多优化,而下面介绍的volatile则是轻量级的synchronized。如果一个变量使用volatile,则它比使用synchronized的成本更加低,因为它不会引起线程上下文的切换和调度。Java语言规范对vo 阅读全文
posted @ 2018-04-12 11:31 Call_Me_Tiger_Fu 阅读(262) 评论(0) 推荐(0) 编辑
摘要: 通过前面一章我们了解了synchronized是一个重量级的锁,虽然JVM对它做了很多优化,而下面介绍的volatile则是轻量级的synchronized。如果一个变量使用volatile,则它比使用synchronized的成本更加低,因为它不会引起线程上下文的切换和调度。Java语言规范对vo 阅读全文
posted @ 2018-04-12 11:30 Call_Me_Tiger_Fu 阅读(351) 评论(0) 推荐(0) 编辑