BlockingQueue:
不接受 null 元素;可以是限定容量的;实现是线程安全的;主要用于生产者-使用者队列;
方法 抛出异常 返回特定的值 阻塞 超时
插入 add(e) offer(e) put(e) offer(e, time, unit)
移除 remove() poll() take() poll(time, unit)
检查 element() peek() 不可用 不可用
实现类:
ArrayBlockingQueue:基于数组实现的有界阻塞队列
DelayQueue:无界阻塞队列,每个元素都有一个延迟时间,在延迟时间之后才释放元素。
LinkedBlockingQueue:基于链表实现的无界(可以指定)阻塞队列,默认大小Integer.MAX_VALUE,有较好的吞吐量,但可预测性差。
PriorityBlockingQueue:具有优先级的无界阻塞队列,所有元素都必须可比较,顺序:非先进先出。
SynchronousQueue:只有一个元素的同步队列,若队列中有元素插入操作将被阻塞,直到队列中的元素被其他线程取走。
继承接口:
BlockingDeque:阻塞双端队列,
LinkedBlockingDeque:支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除);并且,该阻塞队列是支持线程安全。
TransferQueue:生产者会一直阻塞直到所添加到队列的元素被某一个消费者所消费
LinkedTransferQueue:采用一种预占模式,消费者线程取元素时,如果队列不为空,则直接取走数据,若队列为空,那就生成一个节点(节点元素为null)入队,然后消费者线程被等待在这个节点上,后面生产者线程入队时发现有一个元素为null的节点,生产者线程就不入队了,直接就将元素填充到该节点,并唤醒该节点等待的线程,被唤醒的消费者线程取走元素,从调用的方法返回。
Lock锁和Condition条件
ReentrantLock(重入锁)
ReentrantReadWriteLock(读写锁)
Tools
CountDownLatch:它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。
final CountDownLatch countDownLatch=new CountDownLatch(2);
new Thread(new Runnable(){
@Override
public void run() {
System.out.println(等待");
try {
countDownLatch.await(); //已结给上锁了
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("1开始");
try {
Thread.sleep(3000);
countDownLatch.countDown();
System.out.println("1结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("2开始");
try {
Thread.sleep(5000);
countDownLatch.countDown();
System.out.println("2结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
CyclicBarrier:让一组线程等待至某个状态之后再全部同时执行。
public static void main(String[] args) {
int N = 4;
CyclicBarrier barrier = new CyclicBarrier(N);
for(int i=0;i<N;i++)
new Writer(barrier).start();
}
static class Writer extends Thread{
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");
try {
Thread.sleep(5000); //以睡眠来模拟写入数据操作
System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
System.out.println("所有线程写入完毕,继续处理其他任务...");
}
}
Semaphore:可以控制同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
public static void main(String[] args) {
int N = 8; //工人数
Semaphore semaphore = new Semaphore(5); //机器数目
for(int i=0;i<N;i++)
new Worker(i,semaphore).start();
}
static class Worker extends Thread{
private int num;
private Semaphore semaphore;
public Worker(int num,Semaphore semaphore){
this.num = num;
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("工人"+this.num+"占用一个机器在生产...");
Thread.sleep(2000);
System.out.println("工人"+this.num+"释放出机器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
总结:CountDownLatch和CyclicBarrier都能够实现线程之间的等待,CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的;Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。
信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制。
【 java.util.concurrent核心类 】
1)Executor:具有Runnable任务的执行者。
2)ExecutorService:一个线程池管理者,其实现类有多种,我会介绍一部分,我们能把Runnable,Callable提交到池中让其调度。
3)Semaphore:一个计数信号量。
4)ReentrantLock:一个可重入的互斥锁定Lock,功能类似synchronized,但要强大的多。
5)Future:是与Runnable,Callable进行交互的接口,比如一个线程执行结束后取返回的结果等,还提供了cancel终止线程。
6)BlockingQueue:阻塞队列。
7)CompletionService:ExecutorService的扩展,可以获得线程执行结果的。
8)CountDownLatch:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
9)CyclicBarrier:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点。
10)Future:表示异步计算的结果。
11)ScheduldExecutorService:一个ExecutorService,可安排在给定的延迟后运行或定期执行的命令。
JUC集合类
List的主要实现类包括:
CopyOnWriteArrayList:相当于线程安全的ArrayList,它实现了List接口,他是线程安全的。
Set的主要实现类包括:
CopyOnWriteArraySet:相当于线程安全的HashSet,内部使用 CopyOnWriteArrayList 。
ConcurrentSkipListSet:一个基于 ConcurrentSkipListMap 的可缩放并发 NavigableSet 实现,内部排序是有序的。
Map的主要实现类包括:
ConcurrentHashMap:支持获取的完全并发和更新的所期望可调整并发的哈希表。
ConcurrentSkipListMap:可缩放的并发 ConcurrentNavigableMap 实现,内部排序是有序的Map,该类为线程安全的。
Queue的主要实现类包括:
ArrayBlockingQueue:一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序;
LinkedBlockingQueue:一个基于已链接节点的、范围任意的 blocking queue。此队列按 FIFO(先进先出)排序元素;
LinkedBlockingDeque:一个基于已链接节点的、任选范围的阻塞双端队列;
ConcurrentLinkedQueue:一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序;
ConcurrentLinkedDeque:是双向链表实现的无界队列,该队列同时支持FIFO和FILO两种操作方式。
JUC
最新推荐文章于 2023-11-14 21:51:58 发布