并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解

在多线程编程过程中,为了业务解耦和架构设计,经常会使用并发容器用于存储多线程间的共享数据,这样不仅可以保证线程安全,还可以简化各个线程操作。例如在“生产者-消费者”问题中,会使用阻塞队列(BlockingQueue)作为数据容器,关于BlockingQueue可以[看这篇文章](https://www.jianshu.com/p/c422ed5ea9ce)。为了加深对阻塞队列的理解,唯一的方式是对其实验原理进行理解,这篇文章就主要来看看ArrayBlockingQueue和LinkedBlockingQueue的实现原理。

并发容器之BlockingQueue

在实际编程中,会经常使用到JDK中Collection集合框架中的各种容器类如实现List,Map,Queue接口的容器类,但是这些容器类基本上不是线程安全的,除了使用Collections可以将其转换为线程安全的容器,Doug Lea大师为我们都准备了对应的线程安全的容器,如实现List接口的CopyOnWriteArrayList([关于CopyOnWriteArrayList可以看这篇文章](https://www.jianshu.com/p/24ae1d6e3ce0)),实现Map接口的ConcurrentHashMap([关于ConcurrentHashMap可以看这篇文章](https://www.jianshu.com/p/c02a5627d0a5)),实现Queue接口的ConcurrentLinkedQueue([关于ConcurrentLinkedQueue可以看这篇文章](https://www.jianshu.com/p/001c45716232))。

并发容器之CopyOnWriteArrayList

java学习者都清楚ArrayList并不是线程安全的,在读线程在读取ArrayList的时候如果有写线程在写数据的时候,基于fast-fail机制,会抛出**ConcurrentModificationException**异常,也就是说ArrayList并不是一个线程安全的容器,当然您可以用Vector,或者使用Collections的静态方法将ArrayList包装成一个线程安全的类,但是这些方式都是采用java关键字synchronzied对方法进行修饰,利用独占式锁来保证线程安全的。但是,由于独占式锁在同一时刻只有一个线程能够获取到对象监视器,很显然这种方式效率并不是太高。

大白话说java并发工具类-CountDownLatch,CyclicBarrier

在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join方法,让主线程等待被join的线程执行完之后,主线程才能继续往下执行。当然,使用线程间消息通信机制也可以完成。其实,java并发工具类中为我们提供了类似“倒计时”这样的工具类,可以十分方便的完成所说的这种业务场景。

大白话说java并发工具类-Semaphore,Exchanger

Semaphore可以理解为**信号量**,用于控制资源能够被并发访问的线程数量,以保证多个线程能够合理的使用特定资源。Semaphore就相当于一个许可证,线程需要先通过acquire方法获取该许可证,该线程才能继续往下执行,否则只能在该方法出阻塞等待。当执行完业务功能后,需要通过`release()`方法将许可证归还,以便其他线程能够获得许可证继续执行。

线程池ThreadPoolExecutor实现原理

在实际使用中,线程是很占用系统资源的,如果对线程管理不善很容易导致系统问题。因此,在大多数并发框架中都会使用**线程池**来管理线程,使用线程池管理线程主要有如下好处

线程池之ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor可以用来在给定延时后执行异步任务或者周期性执行任务,相对于任务调度的Timer来说,其功能更加强大,Timer只能使用一个后台线程执行任务,而ScheduledThreadPoolExecutor则可以通过构造函数来指定后台线程的个数。

详解Condition的await和signal等待通知机制

任何一个java对象都天然继承于Object类,在线程间实现通信的往往会应用到Object的几个方法,比如wait(),wait(long timeout),wait(long timeout, int nanos)与notify(),notifyAll()几个方法实现等待/通知机制,同样的, 在java Lock体系下依然会有同样的方法实现等待/通知机制。从整体上来看**Object的wait和notify/notify是与对象监视器配合完成线程间的等待/通知机制,而Condition与Lock配合完成等待通知机制,前者是java底层级别的,后者是语言级别的,具有更高的可控制性和扩展性**。两者除了在使用方式上不同外,在**功能特性**上还是有很多的不同

线程状态转换以及基本操作

一个java程序从main()方法开始执行,然后按照既定的代码逻辑执行,看似没有其他线程参与,但实际上java程序天生就是一个多线程程序,包含了:(1)分发处理发送给给JVM信号的线程;(2)调用对象的finalize方法的线程;(3)清除Reference的线程;(4)main线程,用户程序的入口。

你以为你真的了解final吗?

final可以修饰**变量,方法和类**,用于表示所修饰的内容一旦赋值之后就不会再被改变,比如String类就是一个final类型的类。即使能够知道final具体的使用方法,我想对**final在多线程中存在的重排序问题**也很容易忽略,希望能够一起做下探讨。