JUC介绍

一、并发与并行

1.并发

早期计算机CPU是单核的,为了提高CPU的利用率,减少等待时间,使用了并发
并发就是将CPU资源合理分配给多个任务,当一个任务执行I/O操作时,转去执行其他任务
请添加图片描述

2.并行

针对多核CPU,并行就是多核CPU同时独立执行一个任务,而且多个任务互不干扰
请添加图片描述

二、进程与线程

1.进程

指系统中正在运行的一个应用程序的一个实例

2.线程

一个进程中存在多个线程,是程序执行的最小单位
线程的状态:

  1. NEW(新建)
    线程对象已经创建,但未运行
  2. RUNNABLE(可运行)
    线程已启动,准备运行
  3. BLOCKED(阻塞)
    线程试图获取已被持有的锁,会被阻塞直到被释放
  4. WAITING(等待)
    线程无限期处于等待状态,等待其他线程执行特定动作
  5. TIMED_WAITING(限时等待)
    线程处于有限期等待状态,等待其他线程执行特定动作或者时间间隔
  6. TERMINATED(终止)
    线程执行完或因异常被终止

三、wait和sleep的区别

1.使用方式

wait() 方法属于Object类
sleep() 方法属于Thread方法,静态方法

2.对锁的影响

wait() 方法会释放锁
sleep() 方法不会释放锁

3.唤醒方式

wait() 方法需要手动唤醒 notify() 或 notifyAll()
sleep() 方法自动唤醒

四、JUC中的原子类

1.基本类型原子类

1)Atomiclnteger 整型原子类

主要方法:

  • get() :获取当前值
  • set(int newValue) :设置当前值
  • incrementAndGet() :自增当前值并返回结果
  • decrementAndGet() :自减当前值并返回结果
  • getAndIncrement() :自增当前值并返回原值
  • getAndDecrement() :自减当前值并返回原值
  • addAndGet(int delta) :当前值加上指定值并返回结果
  • getAndAdd(int delta) :当前值加上指定值并返回原值
  • compareAndSet(int expect, int updater) :如果当前值为预期值,则将当前值设置为更新值,否则返回false

2)AtomicLong 长整型原子类
主要方法与AtomicInteger类似,处理的是64位长整型值

3)AtomicReference 引用类型原子类
可以存储任何类型对象,可以用来创建复杂的原子数据结构,如原子对列,栈等

4)AtomicBoolean 布尔型原子类
提供了线程安全的布尔值更新

2.原子数组

AtomicIntegerArray 整型原子数组
AtomicLongArray 长整型原子数组
AtomicReferenceArray 引用类型原子数组
常用方法

  • get(index) :返回指定索引处的值
  • compareAndSet(index, expectedValue, newValue) :如果指定索引处的值为预期值,则设置为给定的新值
  • getAndIncrement(index) :指定索引处自增返回旧值
  • getAndDecrement(index): 指定索引处的值自减返回旧值
  • getAndAdd(index, delta): 指定索引处的值加上给定的增量并返回旧值
  • addAndGet(index, delta): 指定索引处的值加上给定的增量并返回新值

3.计数器(LongAdder)

主要用于需要的频繁更新和读取的大量数据并发场景,使用无锁技术以及基于分段的技术器实现高性能的原子操作,性能比AtomicLong高

方法:

  • add(long x) :增加指定值
  • increment() :自增
  • decrement() :自减
  • reset() :重置计数器
  • sum() :获取当前总和

五、JUC包中的辅助类

1.CountDownLatch

允许一个或多个线程等待其他线程完成某些操作,当计数器的值减为零时,所有等待的线程被释放

主要方法:

  • 构造函数CountDownLatch(int coun):构造一个带有指定技术的CountDownLatch实例
  • countDown() :每次调用方法计数减一
  • await() :阻塞当前线程,直到计数为0或超时

2.CyclicBarrier 同步辅助类

可以让多个线程互相等待,直到所有线程到达屏障点

主要方法:

  1. 构造方法:
  • CyclicBarrier(int parties): 创建一个新的 CyclicBarrier,参数 parties 指的是需要等待的线程数量。
  • CyclicBarrier(int parties, Runnable barrierAction): 与第一个构造函数类似,但当所有线程都到达屏障时,会有一个额外的Runnable 任务被执行
  1. 成员方法
  • await():阻塞当前线程,直到所有参与的线程都调用了此方法。
  • reset(): 重置屏障,取消所有正在等待的线程。
  • getParties(): 返回屏障的参与者数量。
  • isBroken(): 返回一个布尔值表示屏障是否已被中断或超时。

3.Semaphore 信号量

用于控制同时访问某个资源的线程数量。它的本质是一个“共享锁“。

主要方法:

  1. 构造函数:
  • Semaphore(int permits):创建一个具有给定数量许可的 Semaphore。
  • Semaphore(int permits, boolean fair):创建一个具有给定数量许可的 Semaphore,并且可以选择是否公平分配许可。
  1. 获取许可:
  • acquire():等待直到获取一个许可,如果所有许可都被占用,则线程将被阻塞。
  • acquireUninterruptibly():等待直到获取一个许可,即使线程被中断也不会抛出异常。
  • tryAcquire():尝试获取一个许可,如果许可可用则立即返回 true,否则返回 false。
  • tryAcquire(long timeout, TimeUnit unit):尝试在给定时间内获取一个许可,如果在超时时间内许可可用则立即返回 true,否则返回 false。
  1. 释放许可:
  • release():释放一个许可,增加可用的许可数量。
  1. 查询状态:
  • availablePermits():返回当前可用的许可数量。
  • getQueueLength():返回等待获取许可的线程数量。
  • hasQueuedThreads():返回是否有线程正在等待获取许可。
  • drainPermits():获取并消耗所有可用的许可。

六、ConcurrentHashMap

ConcurrentHashMap是Java中一个线程安全的HashMap实现,它被设计用于在多线程环境中高效地存储键值对。
在ConcurrentHashMap中,key和value都不允许为null

主要方法:

  • put(key, value):插入或更新键值对。
  • get(key):获取键对应的值。
  • remove(key):删除指定键的映射。
  • containsKey(key):检查是否存在指定的键。
  • forEach(BiConsumer):遍历所有键值对。
  • computeIfAbsent(key, mappingFunction):如果键不存在,则计算并放入新值。

七、Synchronized和lock的区别

1.synchronzied是关键字,lock是java.util.concurrent.locks包下的接口
2.synchronized是隐藏的加锁,lock是显示的加锁
3.synchronized作用于方法上面,lock只能用于方法块上面
4.synchronized底层采用的是objectMonitor(对象内置锁) ,lock采用的是AQS(AbstractQueuedSynchronizer 抽象队列同步器)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值