zoukankan      html  css  js  c++  java
  • 秋招之路9:juc并发

    j.u.c是java.util.concurrent的简称

    通过查api,了解到是由以下这三个组成的。

    juc包图

    锁的两种实现方式

    java并发编程,关于锁的实现方式有两种:

    1.基于synchronized关键字实现同步,jvm内置锁,也叫隐式锁,由jvm自动加锁和解锁
    2.juc下的lock接口实现的更加灵活的锁的实现方式,也叫显示锁,需要手动加锁和解锁

    重要分类

    locks部分:显示锁(互斥锁和读写锁)相关;
    atomic部分:原子变量类相关,是构建非阻塞队列算法的基础,使用CAS实现;
    executor部分:线程池相关;
    collections部分:并发容器相关;
    tools部分:同步工具相关,如信号量,闭锁,栅栏等;
    

    lock图

    ReentrantLock锁

    ReentrantLock,可重入锁,是一种递归无阻塞的同步机制。
    它可以等同于 synchronized的使用,但是 ReentrantLock 提供了比synchronized 更强大、灵活的锁机制,可以减少死锁发生的概率。
    其中ReentrantLock里面涉及的公平锁与非公平锁;重入锁和非可重入锁。围绕着去实现的核心内在原理就是AQS抽象队列同步器。
    里面ReentrantLock里面的变量

    head 队列头
    tail 队列尾
    state 计数上锁次数
    exlusiveOwnerThread 当前占有的线程
    
    • ReentrantLock 实现 Lock 接口,基于内部的 Sync 实现(Sync是ReentrantLock的一个内部类)。
    private final Sync sync;
    abstract static class Sync extends AbstractQueuedSynchronizer {};
    public ReentrantLock() {
        sync = new NonfairSync();
    }
    
    • Sync 实现 AQS ,提供了 FairSync 和 NonFairSync 两种实现(NonfairSync和FairSync 的两个子类)。
    static final class NonfairSync extends Sync {};
    static final class FairSync extends Sync {};
    

    condition

    Condition 和 Lock 一起使用以实现等待/通知模式,通过 await()和singnal() 来阻塞和唤醒线程。
    传送门

    //一个条件队列的典型例子
    while(!conditionPredition)
        lock.wait();
    doSomething();
    

    Condition 是一种广义上的条件队列。
    他为线程提供了一种更为灵活的等待 / 通知模式,线程在调用 await 方法后执行挂起操作,直到线程等待的某个条件为真时才会被唤醒。
    Condition 必须要配合 Lock 一起使用,因为对共享状态变量的访问发生在多线程环境下。
    一个 Condition 的实例必须与一个 Lock 绑定, Condition 一般是 Lock 的内部实现。

    ReentrantReadWriteLock

    读写锁维护着一对锁,一个读锁和一个写锁
    通过分离读锁和写锁,使得并发性比一般的排他锁有了较大的提升:

    1.在同一时间,可以允许多个读线程同时访问。
    2.但是,在写线程访问时,所有读线程和写线程都会被阻塞。

    特性:

    1. 公平性:支持公平性和非公平性。
    2. 重入性:支持重入。读写锁最多支持 65535 个递归写入锁和 65535 个递归读取锁。
    3. 锁降级:遵循获取写锁,再获取读锁,最后释放写锁的次序,如此写锁能够降级成为读锁。
      ReentrantReadWriteLock 实现 ReadWriteLock 接口,可重入的读写锁实现类。
    public class ReentrantReadWriteLock
            implements ReadWriteLock, java.io.Serializable {
        /** Inner class providing readlock */
        private final ReentrantReadWriteLock.ReadLock readerLock;
        /** Inner class providing writelock */
        private final ReentrantReadWriteLock.WriteLock writerLock;
    

    在同步状态上,为了表示两把锁,将一个 32 位整型分为高 16 位和低 16 位,分别表示读和写的状态

             /*
             * Read vs write count extraction constants and functions.
             * Lock state is logically divided into two unsigned shorts:
             * The lower one representing the exclusive (writer) lock hold count,
             * and the upper the shared (reader) hold count.
             */
    
            static final int SHARED_SHIFT   = 16;
            static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
            static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
            static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
    
            /** Returns the number of shared holds represented in count  */
            static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
    
  • 相关阅读:
    【Android】带底部指示的自定义ViewPager控件
    【Android】百度地图自定义弹出窗口
    【Linux配置】vim配置文件内容
    【Linux Tips】登陆,提示符,别名
    读《effective C++》2
    读《effective C++》1
    【PAT_Basic日记】1005. 继续(3n+1)猜想
    【PAT_Basic日记】1004 成绩排名
    【PAT_Basic日记】1002. 写出这个数
    【PAT_Basic日记】1001. 害死人不偿命的(3n+1)猜想
  • 原文地址:https://www.cnblogs.com/whyaza/p/12348215.html
Copyright © 2011-2022 走看看