多线程与高并发六-容器

容器图

7616411c2983db72b19ba36a1f64f3d6

1、MAP

一、不须要同步的状况

HashMap
TreeMap
LinkedHashMapjava

二、并发不高的状况

Hashtable
Collections.synchronizedMap();数组

三、高并发的状况

ConcurrentHashMap (分红16段,而后给各段加锁,多线程访问小分段,因此效率高些)
ConcurrentHashSet
ConcurrentSkipListMap 跳表,已排序,能够用来快速查找多线程

2、LIST

一、不须要同步的状况

ArrayList
LinkedList并发

二、并发的状况

Vector
Collections.synchronizedList( )ide

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

3、QUEUE

一、不须要同步的状况

LinkedList
PriorityQueue性能

二、高并发的状况

  1. 高性能队列:CocurrentLinkedQueue / concurrentArrayQueuethis

  2. 阻塞队列:BlockingQueue线程

    BlockingQueue能够做为多个线程之间的数据共享通道。3d

    a4b64a6ceaf3a5762979838e9e91a463

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 的关键。

  1. 执行定时任务: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。默认排了序,每一个元素须要等一段时间才能被取出来,每一个元素本身会记录时间,等待时间最短的排在前面,最早取出来。

  1. 转发消息: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();
        }
}

使用时需先启动消费者,后启动生产者。能够用于实时消息处理。

  1. 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");
}
相关文章
相关标签/搜索