YNZH's Blog

java.util.concurrent.* 总结

AQS(模板方法设计模式)

1
2
3
4
5
6
7
<ul>
<li>{@link #tryAcquire}
<li>{@link #tryRelease}
<li>{@link #tryAcquireShared}
<li>{@link #tryReleaseShared}
<li>{@link #isHeldExclusively}
</ul>

CLH队列

1
2
3
4
5
6
7
8
9
10
Node{
volatile int waitStatus;
volatile Node prev;
volatile Node next;
volatile Thread thread;
}

* +------+ prev +-----+ +-----+
* head | | <----> | | <----> | | tail
* +------+ next +-----+ +-----+

锁(LockSupport)

ReentrantLock:

ReentrantReadWriteLock :

锁降级(在加写锁之后可以加读锁,但是读锁不可以加写锁,缓存击穿解决方案)

CountDownLatch:

countdown则减一,await等到倒计时为0的时候开始行运行,否则阻塞。底层使用AQS实现

Semaphore:

有N个资源可以被抢占,每当没有资源的时候线程阻塞,否则拿到资源,底层使用AQS实现的

场景

在Hystrix中大量使用得到。例如最多同时支持5000个请求,可以设置资源数为5000,当同时有更多的请求来临时可以阻塞从而达到限流的效果。

CyclicBarrier

循环栏杆,每次到栏杆可以运行一个Runnable的action,注意是可以循环的,底层使用ReentranLock的Condition(wait,notify的代替可以灵活的按条件分类)机制实现的

并发容器

HashMap

ConcurrentHashMap:

1.7segment(继承ReentrantLock)数组实现线程安全,

1.8CAS+Synchronized实现线程安全

ConcurrentSkipListMap:

有序的,线程安全的 代替红黑树的实现,

ConcurrentSkipListSet:

CopyOnWriteArrayList:

占用两块内存写的时候。

同步队列

image-20200427213447351

带有Blocking的全部使用ReentrantLock实现,带有Cocurrent的大部分使用CAS的实现。

ArrayBlockingQueue

必须指定大小,底层ReentrantLock

LinkedBlockingQueue

最大容量Integer.MAX_VALUE,

ConcurrentLinkedQueue/ConcurrentLinkedDeque

底层CAS,容量无限大

SynchronousQueue 数据同步交换的队列

奇葩队列,没有实际存储的空间,必须put一个take一个

1
2
3
4
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);

DelayQueue 延时队列

可以使放入队列的元素在指定的延时后才被消费者取出,元素需要实现Delayed接口。

ForkJoin

原理

类似与MapReduce模式,通过Pool建立一个线程池,将任务拆分(fork)交给pool中的线程完成,递归的划分到可接受的最小任务,然后将各个fork的任务join到一起返回。 工作原理任务窃取)每个线程有自己的一个任务队列,不同于线程池(只有一个同步队列),当某个线程的任务队列结束之后可以窃取其他线程队列的任务,充分发挥多核cpu的优点

注意

划分的子任务不能为具有阻塞性的任务,不然整个大任务的完成就会阻塞。可以用于parallelSort的排序等非阻塞的场景。

场景

Arrays.parallelSort()等类似的非阻塞的场景


 评论


博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

本站使用 Material X 作为主题 , 总访问量为 次 。
载入天数...载入时分秒...