Java并发之并发容器

先来一张图丫丫金:
这里写图片描述

一、Map

1、不需要同步的情况

HashMap
TreeMap
LinkedHashMap

2、并发不高的情况

Hashtable
Collections.synchronizedMap(Map

3、高并发的情况

ConcurrentHashMap (分成16段,然后给各段加锁,多线程访问小分段,所以效率高些)
ConcurrentHashSet
ConcurrentSkipListMap 跳表,已排序,可以用来快速查找

二、List

1、不需要同步的情况

ArrayList
LinkedList

2、并发的情况

Vector
Collections.synchronizedList( )

CopyOnWriteList
写时复制容器 copy on write 写的时候,复制一份新的供读
多线程环境下,写时效率低,读时效率高
适合写少读多的环境

三、Queue

1、不需要同步的情况

LinkedList
PriorityQueue

2、高并发的情况
  1. 高性能队列:CocurrentLinkedQueue / concurrentArrayQueue
  2. 阻塞队列:BlockingQueue
    这里写图片描述
    BlockingQueue可以作为多个线程之间的数据共享通道。

LinkedBlockingQueue:基于链表实现,适合做无界队列或者边界值非常的大队列
ArrayBlockingQueue(int capacity):基于数组实现,适合做有界队列

//满了不会报异常,但是不会加进去
public boolean offer(E e) {
...
}
//如果满了,就会等待,程序阻塞
public void put(E e) throws InterruptedException {
...
}
//满了报异常
public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
}
//如果空了,就会等待,程序阻塞
public E take() throws InterruptedException {
...
}
//如果队列为空,直接返回null
public E poll() {
...
}

put() 和 take() 方法是体现 Blocking 的关键。
3. 执行定时任务:DelayQueue

public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
    implements BlockingQueue<E> {
}

示例:

static BlockingQueue<MyTask> tasks = new DelayQueue<>();

static class MyTask implements Delayed {
        long runningTime;       
        MyTask(long rt) {
            this.runningTime = rt;
        }

        @Override
        public int compareTo(Delayed o) {
            if(this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS))
                return -1;
            else if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) 
                return 1;
            else 
                return 0;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(runningTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        @Override
        public String toString() {
            return "" + runningTime;
        }
}
MyTask t1 = new MyTask(now + 5000);
tasks.put(t1);

DelayQueue是阻塞无界队列,实现了BlockingQueue。默认排了序,每个元素需要等一段时间才能被取出来,每个元素自己会记录时间,等待时间最短的排在前面,最先取出来。
4. 转发消息:TransferQueue
TransferQueue是一个接口,实现类为:LinkedTransferQueue

// 生产者有数据时首先看有没有消费者,有的话,直接给消费者,不放进队列了
// 没有消费者的话 就阻塞在这里,后面的代码执行不了了
public void transfer(E e) throws InterruptedException {
        if (xfer(e, true, SYNC, 0) != null) {
            Thread.interrupted(); // failure possible only due to interrupt
            throw new InterruptedException();
        }
}

使用时需先启动消费者,后启动生产者。可以用于实时消息处理。
5. SynchronusQueue: 一种特殊TransferQueue,容量为0

//阻塞等待消费者消费  用的是transfer
public void put(E e) throws InterruptedException {
        if (e == null) throw new NullPointerException();
        if (transferer.transfer(e, false, 0) == null) {
            Thread.interrupted();
            throw new InterruptedException();
        }
}
//如果容量不为0,报错
public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
}

猜你喜欢

转载自blog.csdn.net/iluojie/article/details/80146939
今日推荐