JUC

1.Java JUC 简介

在Java 5.0 提供了 java.util.concurrent (简称 JUC )包,在此包中增加了在并发编程中很常用 的实用工具类,用于定义类似于线程的自定义子
系统,包括线程池、异步 IO 和轻量级任务框架。 提供可调的、灵活的线程池。还提供了设计用于 多线程上下文中的 Collection 实现等。

2.volatile 关键字-内存可见性

volatile关键字的作用

3.原子变量-CAS算法

CAS (Compare-And-Swap) 是一种硬件对并发的支持,针对多处理器 操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并 发访问。

  • CAS 是一种无锁的非阻塞算法的实现。
  • CAS 包含了 3 个操作数:
  1. 需要读写的内存值V
  2. 进行比较的值A
  3. 拟写入的新值B
    当且仅当V 的值等于A 时,CAS 通过原子方式用新值B 来更新V 的 值,否则不会执行任何操作。

原子变量

  1. 类AtomicBoolean、AtomicInteger、AtomicLong 和AtomicReference 的实例各自提供对 相应类型单个变量的访问和更新。每个类也为该类型提供适当的实用工具方法。
  2. AtomicIntegerArray、AtomicLongArray 和AtomicReferenceArray 类进一步扩展了原子操 作,对这些类型的数组提供了支持。这些类在为其数组元素提供 volatile 访问语义方 面也引人注目,这对于普通数组来说是不受支持的。

核心方法:boolean compareAndSet(expectedValue, updateValue)

java.util.concurrent.atomic 包下提供了一些原子操作的常用类:
AtomicBoolean 、AtomicInteger 、AtomicLong 、 AtomicReference
AtomicIntegerArray 、AtomicLongArray
AtomicMarkableReference
AtomicReferenceArray
AtomicStampedReference

AtomicInteger类与CAS算法模拟详解

4.ConcurrentHashMap 锁分段机制

  • Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器
    的性能。
  • ConcurrentHashMap 同步容器类是Java 5 增加的一个线程安全的哈希表。对 与多线程的操作,介于HashMap 与Hashtable 之间。内部采用“锁分段” 机制替代 Hashtable 的独占锁。进而提高性能。
  • 此包还提供了设计用于多线程上下文中的 Collection 实现: ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、 CopyOnWriteArrayList 和 CopyOnWriteArraySet。当期望许多线程访问一个给 定collection 时,ConcurrentHashMap 通常优于同步的HashMap, ConcurrentSkipListMap 通常优于同步的 TreeMap。当期望的读数和遍历远远 大于列表的更新数时,CopyOnWriteArrayList 优于同步的ArrayList。
    详见:HashMap、Hashtable、ConcurrentHashMap三者间的异同

5.CountDownLatch 闭锁

  • CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作 之前,它允许一个或多个线程一直等待。
  • 闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活动直到其他活动都完成才继续执行:
    a. 确保某个计算在其需要的所有资源都被初始化之后才继续执行;
    b. 确保某个服务在其依赖的所有其他服务都已经启动之后才启动;
    c. 等待直到某个操作所有参与者都准备就绪再继续执行。
    在这里插入图片描述
    在这里插入图片描述

6.实现Callable 接口

  • Callable 接口类似于Runnable,两者都是为那些其实例可 能被另一个线程执行的类设计的。但是 Runnable 不会返 回结果,并且无法抛出经过检查的异常。
  • Callable 需要依赖FutureTask ,FutureTask 也可以用作闭锁。

多线程详解

7.Lock 同步锁

多线程详解

8.Condition 控制线程通信 线程按序交替

  • Condition 接口描述了可能会与锁有关联的条件变量。这些变量在用 法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的 功能。需要特别指出的是,单个 Lock 可能与多个 Condition 对象关 联。为了避免兼容性问题,Condition 方法的名称与对应的 Object 版 本中的不同。
  • 在 Condition 对象中,与wait、notify 和 notifyAll 方法对应的分别是
    await、signal 和 signalAll。
  • Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得
    Condition 实例,请使用其 newCondition() 方法。

使线程按序交替执行

9.ReadWriteLock 读写锁

  • ReadWriteLock 维护了一对相关的锁,一个用于只读操作, 另一个用于写入操作。只要没有writer,读取锁可以由
    多个reader 线程同时保持。写入锁是独占的。。
  • ReadWriteLock 读取操作通常不会改变共享资源,但执行 写入操作时,必须独占方式来获取锁。对于读取操作占 多数的数据结构。 ReadWriteLock 能提供比独占锁更高 的并发性。而对于只读的数据结构,其中包含的不变性 可以完全不需要考虑加锁操作。

写写/读写 需要“互斥”
读读 不需要互斥

在这里插入图片描述

public class TestReadWriteLock {
	public static void main(String[] args) {
		ReadWriteLockDemo rw = new ReadWriteLockDemo();

		new Thread(new Runnable() {
			@Override
			public void run() {
				rw.set(new Random().nextInt(100));
			}
		},"write:").start();
		
		for (int i = 0; i < 10; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					rw.get();
				}
			},"read:").start();
		}
	}
}

class ReadWriteLockDemo{
	private int number = 0;
	private ReadWriteLock lock = new ReentrantReadWriteLock();
	//读
	public void get() {
		lock.readLock().lock();//上锁
		try {
			System.out.println(Thread.currentThread().getName() + "---" + number);			
		}finally {
			lock.readLock().unlock();//释放锁
		}
	}
	//写
	public void set(int num) {
		lock.writeLock().lock();
		try {
			System.out.println(Thread.currentThread().getName());			
			this.number = num;			
		}finally {
			lock.writeLock().unlock();
		}
	}
} 

10.线程锁

关键:
1.非静态方法的锁默认为 this, 静态方法的锁为对应的 Class 实例
2.某一个时刻内,只能有一个线程持有锁,无论几个方法

  • 同一个对象,调用两个同步方法:执行完一个再执行另一个
  • 两个对象,调用两个同步方法:交替执行
    在这里插入图片描述
  • 同一个对象,调用两个静态同步方法:执行完一个再执行另一个
  • 两个对象,调用两个静态同步方法:执行完一个再执行另一个
    在这里插入图片描述
  • 两个对象一个调用同步方法,一个调用静态同步方法:交替执行

11.线程池

  • 线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在 执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行 任务集时使用的线程)的方法。每个 ThreadPoolExecutor 还维护着一些基本的统计数 据,如完成的任务数。

在这里插入图片描述

12.线程调度

在这里插入图片描述

13.ForkJoinPool 分支/合并框架工作窃取

Fork/Join 框架:就是在必要的情况下,将一个大任务,进行拆分(fork)成 若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行join汇总

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
Fork/Join 框架与线程池的区别

  • 采用 “工作窃取”模式(work-stealing):
    当执行新的任务时它可以将其拆分分成更小的任务执行,并将小任务加 到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队 列中。
  • 相对于一般的线程池实现,fork/join框架的优势体现在对其中包含的任务 的处理方式上.在一般的线程池中,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态。而在fork/join框架实现中, 如果某个子问题由于等待另外一个子问题的完成而无法继续运行。那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行.这种方式减少了线程的等待时间,提高了性能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值