Java多线程之JUC实现原理及常见面试题

121 阅读3分钟

简介

前几篇文章中描述了分布式锁,这次我们重点说明一下JUC,JUC:java.util.concurrent包,又称concurrent包。jdk1.5提供,为多线程高并发编程而提供的包。

进程与线程的区别

简单来说:

  • 进程:一个功能完善的软件,系统分配资源的基本单元。
  • 线程:一个进程至少要包含一个线程,CPU执行的基本单元。

并行与并发的区别

  • 并行:在同一时刻操作不同的资源。
  • 并发:在同一时刻多个线程操作相同的资源。

独占锁

  • Synchronized
    • 是一个关键字
    • 悲观的独占的排他的互斥的不公平的可重入锁
    • 静态同步方法,锁类
    • 普通同步方法,锁对象
    • 同步代码块,锁小括号中的资源
  • ReentrantLock
    • 是一个类
    • 悲观的独占的排他的互斥的可公平可不公平的可重入锁
    • new ReetrantLock()
    • 加解锁的方法:lock.lock/unlock()/tryLock(timeOut,timeUnit)

synchronized和ReentrantLock的区别

  • synchronized使用简单,但是不够灵活,ReentrantLock需要手动的加解锁,需要考虑加解锁的次数
  • 都是可不公平的锁,但是ReentrantLock可公平
  • Synchronized是个关键字,ReentrantLock是一个类
  • ReentrantLock可以响应中断,Synchronized不可中断的
  • 线程间通信方式不同

读写锁

  • ReentReadWriteLock
    • new ReentReadWriteLock()
    • rwLock.readLock().lock()/unlock()
    • rwLock.writeLock.lock()/unlock()
    • 读写锁:读读可并发、读写不可并发、写写不可并发

共享锁

  • CountDownLatch
    • 倒计时器,又称闭锁
    • 一个线程或者一组线程等待另一个或者一组线程执行
    • new CountDownLatch(初始值)
    • countdown方法 初始值-1
    • await方法 阻塞线程,当初始值减为0时,放行
  • CyclicBarrier
    • 循环栅栏
    • 一组相互等待的线程
    • new CyclicBarrier(相互等待的线程数,runnable)
    • await
      • 设置相互等待的等待点
      • 一旦所有线程到达等待点,由最后一个到达等特点的线程来执行runnable任务
  • Semaphore
    • 信号量
    • 使用并发量而资源紧张的情况
    • new Semaphore(资源量)
    • acquire方法
      • 获取一个资源
      • 获取成功才会继续执行,否则等待获取资源
    • release 释放资源

并发容器类

  • List
    • ArrayList
      • 线程不安全的
      • 每次扩展50%
    • Vector
      • 线程安全的
      • 缺点:性能一般,扩展因子100%
    • Collections.synchronizedList
      • 线程安全的
      • 内部类,轻量化
      • 迭代器没有加锁
  • Map
    • HashMap
      • 线程不安全的
    • ConcurrentHashMap
    • ConcurrentSkipListMap
      • 线程安全的
  • Set
    • HashSet
      • 线程不安全
    • CopyOnWriteArraySet
      • 线程安全的
  • COW容器
    • CopyOnWrite
      • 写时复制
      • 读写分离思想
    • 优点:
      • 读的性能高
      • 线程安全
    • 缺点:
      • 写的效率低
      • 占用大量内存
      • 读写不一致

底层原理

  • JMM
    • java内存模型:Java Memery Model
    • 结构:
      • 共享内存、主内存
        • 物理内存条
        • 相当于堆
        • 存放共享变量
      • 工作内存、本地内存
        • 多级高速缓存或者cpu寄存器实现
        • 共享变量的副本
      • 线程对共享变量的操作必须在自己的工作内存中完成,不可以直接操作共享内存
      • 线程间不可以互相操作工作内存,共享变量的值传递必须通过共享内存完成
      • 三个特性:
        • 原子性
          • 不可分割性
          • synchrionized ReentrantLock
          • 原子操作类:AtomicLong AtomicInteger AtomicReference
        • 可见性
          • 先行发生的写操作对后续线程可见
          • synchrionized ReentrantLock
          • voliatile final
        • 有序性
          • 禁止指令重排
            • 单线程都是有序的
            • 多线程都是无序的
          • synchrionized ReentrantLock
          • voliatile
  • voliatile
    • 关键字
    • 本质轻量化的同步机制(简配的synchrionized)
    • Happen-before原子
      • 保证可见性
      • 保证有序性-内存屏障
      • 不保证原子性
    • 度的性能和普通变量一致,写的性能稍弱
  • CAS
    • Compare And Swap
      • 比较并交换
      • 底层是Unsafe类、提供了硬件级别的原子操作
    • 解决多线程并发安全问题的一种乐观锁算法
    • 具体实现类
      • java.util.concurrent.atomic包下提供了一些具体包装类
  • AQS
    • 抽象队列同步器:AbstractQueuedSynchronizer
    • 结构:
      • volatile类型的state
      • CLH队列 FIFO队列、First-in-first-out
      • 实现锁 五个方法
      • 独占锁:tryAcquire、tryRelease
      • 共享锁:tryAcquireShared
      • 判断当前线程是否拥有锁 isHeldExclusively