美文网首页
Java进阶-并发-基础

Java进阶-并发-基础

作者: GIT提交不上 | 来源:发表于2022-04-11 23:20 被阅读0次

    一、线程基础

    参考链接:Java多线程-合集

    1.1 基本概念

    • 原子性:和数据库事务中的原子性一样,满足原子性特性的操作是不可中断的,要么全部执行成功要么全部执行失败。
    • 可见性:一个线程对变量的值进行了修改,其他线程能够立即得知这个修改。
    • 有序性:程序执行的顺序按照代码的先后顺序执行。
    Java线程状态迁移图.png Java内存模型.png 运行时数据区.png

    1.2 AQS-抽象队列同步器

    AQS模型.png

    AbstractQueuedSynchronizer
    https://www.jianshu.com/p/8eadabbcc5a9

    1.3 线程池

    线程池状态转化图.png 任务执行过程.png

    1.4 同步/异步/阻塞/非阻塞

    • 同步与异步描述的是进程/线程相互通信的方式,同步是由调用者主动等待调用的结果,异步是被调用者通过状态、通知等通知调用者, 或通过回调函数处理调用。
    • 阻塞和非阻塞描述的是进程/线程在进行I/O操作时的状态,阻塞是指调用结果返回之前,当前线程会被挂起,非阻塞是指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

    https://www.zhihu.com/question/19732473
    https://blog.csdn.net/qq_39515350/article/details/120854214

    二、JUC包

    • volatile:单例模式-DCL(双端检测)机制。
    instance =  new Test();
    //读取到的instance不为null,instance引用对象可能没有完成初始化
    memory = allocate();  // 1 分配对象内存空间
    instance(memory);  // 2 初始化对象
    instance = memory;  // 3 设置instance指向分配的内存地址,此时!=null
    步骤2和3不存在数据依赖关系,可能存在指令重排
    
    • CAS:底层原理-自旋锁 & Unsafe类(底层汇编),时间戳原子引用解决ABA问题。
    //AtomicInteger#getAndIncrement
    public final int getAndIncrement() {
        //this-当前对象 valueOffset-内存地址偏移量
        return unsafe.getAndAddInt(this, valueOffset, 1);  
    }
    
    //Unsafe类
    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            //主内存真实的值 不断自旋-获取主内存的值
            var5 = this.getIntVolatile(var1, var2);
            //var5 + var4更新值返回 true -- 自旋 比较值
         } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
        return var5;
    }
    
    • List:CopyOnWriteArrayList
    //写时复制思想,读写分离
    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }
    
    • Set:CopyOnWriteArraySet
    //底层也是CopyOnWriteArrayList
    public CopyOnWriteArraySet() {
        al = new CopyOnWriteArrayList<E>();
    }
    
    • Map:ConcurrentHashMap
    • CountDownLatch:使一个线程等待其他线程各自执行完毕后再执行
    • CyclicBarrier:让所有线程都等待完成后才会继续下一步行动
    • Semaphore:1)用于多个共享资源的互斥使用 2)用于并发线程数的控制

    CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。Semaphore和锁类似,它一般用于控制对某组资源的访问权限。

    • 死锁:两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉它们都将无法推进下去。
    jps -l 
    jstack -l pid > jstack.out  
    https://fastthread.io/
    
    • ThreadPool:控制运行的线程数量,底层是阻塞队列。
    CPU密集型:任务需要大量的计算,没有阻塞,CPU一致全速运行;公式:CPU核数+1个线程的线程池。
    I/O密集型:公式:2*CPU核数;公式:CPU核数/(1-阻塞系数),阻塞系数在0.8~0.9之间。
    //获取PCU核数
    Runtime.getRuntime().availableProcessors()
    
    • ThreadLocal:把ThreadLocal看成一个全局Map<Thread, Object>,每个线程获取ThreadLocal变量时,总是使用Thread自身作为key。相当于给每个线程都开辟了一个独立的存储空间,各个线程的ThreadLocal关联的实例互不干扰。

    • 锁:对象锁是用来控制实例方法之间的同步,而类锁是用来控制静态方法(或者静态变量互斥体)之间的同步的。

    https://www.shangmayuan.com/a/5845a0a8e2dc4e86b7f3c143.html

    相关文章

      网友评论

          本文标题:Java进阶-并发-基础

          本文链接:https://www.haomeiwen.com/subject/qljusrtx.html