CHuiL

从reentrantlock的实现看aqs(abstractqueuedsynchronizer)的原理及应用

并发

[TOC] java concurrent包中常用同步工具原理 java AQS(AbstractQueuedSynchronizer) AQS是一个框架,用于帮助实现依赖于FIFO等待队列(Thread)的阻塞锁和相关同步器; 他是一个抽象类,有个单原子int值表示状态,有个队列来管理等待线程。 他提供基本的获取和更改状态值的方法,并在内部实现了尝试获取失败后,对当前线程进行入队和阻...

synchronized底层实现

并发

一般描述 synchronized的实现主要利用的Monitor对象,每个类对象都会有一个Monitor对象,在java6之前,monitor的实现完全依靠操作系统内部的互斥锁(Mutex Lock),需要进行用户态到内核态的切换,是个无差别的重量级操作; 而在java6之后,jvm对其进行优化,实现了锁的升级,即从偏向锁升级到轻量级锁,再进一步升级为重量级锁,同时还有锁粗化和锁消除的优...

如何保证集合是线程安全的?

并发

容器线程安全 可以使用传统的同步容器,如hashTable,也可以使用同步包装器Collecetions.synchronzied*方法,来给原本不同步的容器包装为同步容器;以及通过使用并发包中的线程安全容器类来保证线程安全,如各种并发容器,比如 ConcurrentHashMap、CopyOnWriteArrayList。各种线程安全队列(Queue/Deque),如 ArrayBloc...

java内存模型(jmm)

并发

共享内存多核系统 在多处理器的系统中,没饿过处理器都有自己的高速缓存,而他们又共享同一主内存,这种系统成为共享内存多核系统; 由于各个核在计算的过程,都需要将主内存中的数据读取到核私有的高速缓存中,如果多个处理器都运算到了同一块主内存的数据,那么该以哪一块为主?这就导致了缓存不一致,需要解决一致性问题; java 主内存和工作内存 首先先放一张jvm内存布局图 java内存...

java锁优化

并发

为什么要优化? 为什么阻塞线程和挂起线程的操作都需要从用户态转入内核态,这是要耗费很多处理器时间的;并且常见的同步场景有如下几种情况 共享数据的锁定状态只会持续很短一段时间,可能必挂起线程唤醒线程的操作时间还短 大部分情况下,同一时刻只有一个线程会获得该对象的锁 自旋锁与自适应锁 为了不让获取不到锁的线程陷入阻塞,可以让该线程陷入自旋,即让他不断的重试获取锁,执行一个忙循环。...

并发的三种特性

并发

并发的三种特性即 原子性,可见性和有序性; 原子性 即一组操作,全部执行的过程中不能被打断,要么就全部不执行;在我们讨论一个操作是否具有原子性时,其实就讨论这个操作的多个子操作,在实际执行的过程中是否会被随机调度打断;(理解原子性要有个范围的意识,大到我们对一个对象的增删查改,可以通过lock工具来保证原子性,小到具体某一个动作的指令,比如赋值操作可能分为载入数据,...

先行发生原则

并发

先行发生原则可以用来判断并发环境下数据是否存在竞争,线程是否安全得非常有用得手段。用来判断解决并发环境下两个操作之间是否可能存在冲突的所有问题; 满足以下规则的操作,即没有冲突,线程安全; 程序次序规则 同一个线程内,书写在前面得操作先行发生与书写在后面的操作;前面的代码的执行结果对于==依赖它的==后面代码来说是可见的; int a = 3;//代码1 int b = a + 1;...

连接查询的本质

连接的本质就是笛卡尔积,不过是根据条件筛选出来的笛卡尔积; 内外连接的差别 就像我们在计算笛卡尔积那样,我们总是要先选择一个集合,然后在从这个集合选取出一条记录来与另一个集合中的记录匹配一样,我们同样需要先选择一个表,来作为我们的驱动表,另外一个表就是被驱动表; 我们先根据针对驱动表的where查询条件,先筛选一遍驱动表的集合,然后在从这个集合中,取一条记录,与被驱动表的记录进行匹配,被驱...

jvm内存布局

jvm

堆区(heap) 主要存储着几乎所有的实例对象,占用内存空间是所有区域中最大的,线程之间共享使用,堆由垃圾收集器自动回收;堆的大小可以设置,可以设置为在一定大小范围内动态调整,也可以将最大最小值设置为一样来表示为固定大小,线上生产环境中为了避免不必要的GC后调整堆大小带来的额外压力,建议将其大小固定;堆也是OOM故障的主要发生地; 区域主要分为新生代和老年代,新生代有Eden区和Sur...

java nio

nio

基本io模型 select/poll epoll的区别 select和poll都是需要传递所有待监听的文件描述符给内核,然后内核会去查找每个fd是否准备好,当fd很多的时候,效率会直线下降,之后内核返回一个就绪的文件描述符集合,我们需要遍历所有描述符以查看是否在返回的集合中;处理完之后重新调用时还需要再一次传递完整的文件描述符;当检查大量的文件描述符时,需用从用户态到内核态来回拷贝这些...