CompletableFuture基本用法

对比

  • Future:我们的目的都是获取异步任务的结果,但是对于Future来说,只能通过get方法或者死循环判断isDone来获取。异常情况就更是难办。
  • CompletableFuture:只要我们设置好回调函数即可实现:
  1. 只要任务完成,即执行我们设置的函数(不用再去考虑什么时候任务完成)
  2. 如果发生异常,同样会执行我们处理异常的函数,甚至连默认返回值都有(异常情况处理更加省力)
  3. 如果有复杂任务,比如依赖问题,组合问题等,同样可以写好处理函数来处理(能应付复杂任务的处理)
阅读更多

Compare-and-Swap

CAS是乐观锁的一种思想,它假设线程对资源的访问是没有冲突的,同时所有的线程执行都不需要等待,可以持续执行。如果有冲突的话,就用比较+交换的方式来检测冲突,有冲突就不断重试。

CAS的全称是Compare-and-Swap,也就是比较并交换,它包含了三个参数:V,A,B,V表示要读写的内存位置,A表示旧的预期值,B表示新值,当执行CAS时,只有当V的值等于预期值A时,才会把V的值改为B,这样的方式可以让多个线程同时去修改,但也会因为线程操作失败而不断重试,对CPU有一定程序上的开销。
img.png

参考文章

AtomicInteger&无锁对象引用:AtomicReference

AtomicInteger介绍

AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减。

AtomicInteger使用场景

AtomicInteger提供原子操作来进行Integer的使用,因此十分适合高并发情况下的使用。

1.作为多个线程同时使用的原子计数器。

2.在比较和交换操作中实现非阻塞算法。

AtomicInteger作为原子计数器

要将其用作计数器,AtomicInteger类提供了一些方法来原子地执行加减运算。

1
2
3
4
5
6
addAndGet():以原子方式将给定值添加到当前值,并在添加后返回新值。
getAndAdd():以原子方式将给定值添加到当前值并返回旧值。
crementAndGet():以原子方式将当前值增加1,并在增加之后返回新值。 它等效于++ i操作。
getAndIncrement():以原子方式递增当前值并返回旧值。 它等效于i ++操作。
decrementAndGet():以原子方式将当前值减1,并在减后返回新值。 它等效于i-操作。
getAndDecrement():以原子方式减少当前值并返回旧值。 它等效于– -i操作。

AtomicInteger源码部分讲解

阅读更多

线程 方法

method 什么类的方法 描述
wait() notify() notifyAll() Object的本地final方法,无法被重写 实现线程间的通信
在线程中调用 wait() 方法,将阻塞当前线程,直至等到其他线程调用了调用 notify() 方法或 notifyAll() 方法进行通知之后,当前线程才能从 wait() 方法出返回,继续执行下面的操作。
park() unpark() 工具类LockSupport 1.park和unpark是以线程为单位精确阻塞和唤醒线程的;
2.阻塞和唤醒的先后执行顺序可以不一样;
await和signal Condition Object的wait和notify/notify是与对象监视器配合完成线程间的等待/通知机制,而Condition与Lock配合完成等待通知机制,前者是java底层级别的,后者是语言级别的,具备更高的可控制性和扩展性
join() thread 控制线程执行顺序
阅读更多

AbstractQueuedSynchronizer

AQS (AbstractQueuedSynchronizer) 抽象类的队列式同步器

J.U.C是基于AQS实现的,AQS是一个同步器,设计模式是模板模式
核心数据结构:双向链表 + state(锁状态)
底层操作:CAS

原理概览

AQS核心思想是,如果被请求的共享资源空闲,那么就将当前请求资源的线程设置为有效的工作线程,将共享资源设置为锁定状态;如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配。这个机制主要用的是CLH队列的变体实现的,将暂时获取不到锁的线程加入到队列中。

CLH:Craig、Landin and Hagersten队列,是单向链表,AQS中的队列是CLH变体的虚拟双向队列(FIFO),AQS是通过将每条请求共享资源的线程封装成一个节点来实现锁的分配。

img.png

阅读更多