JDK并发容器和BlockingQueue

JDK的并发容器

  • Map类

    1. HashMap,位于java.util包下,是不安全的,可以采用Collections工具类来进行包装

      public static Map m = Collections.synchronizedMap(new HashMap());
      

      这样得到的Map就是线程安全的,但是在多线程环境下性能表现不是很好,因为它是通过加锁的方式,会导致其他线程对Map的操作全部等待

    2. ConcurrentHashMap,位于java.util.concurrent包下,线程安全,采用锁分段技术,将大锁换小锁,提高性能

  • List类

    1. 基于数组实现的:ArrayList和vector,内部都是利用数组实现的,但ArrayList是不安全的,而vector是安全的,并且,其子类stack也是线程安全的,同样
    2. 基于链表实现的:LinkedList——既实现了List接口,也实现了Deque接口,Deque接口不仅可以当做双端队列,还可以当做栈来使用,同样也是线程不安全的,对于这几个不安全的List类,均可以使用Collections工具类相应的synchronizedXXX()方法来实现线程安全
    3. 高效读写的队列:ConcurrentLinkedQueue,使用链表作为数据结构,高并发环境下性能表现最好的队列

数据共享通道:BlockingQueue

  • 线程A和线程B互相通信的一种手段,我们希望线程A能够通知线程B,同时线程A不需要知道线程B的存在,使得整个系统低耦合,当系统升级线程B为线程C的时候,可以不用修改线程A
  • 利用数据共享通道BlockingQueue能够实现
  • 阻塞队列可以让服务线程在队列为空的时候等待,当有新的任务进入队列后,再自动将服务线程唤醒去处理相应的任务
  • 以put()方法为例,队列压入元素有offer()方法和put()方法,对于offer()方法,如果队列已满,就会立即返回false,而put()方法一旦满了,则会等待,直到队列中有空闲的位置。底层实现使用了重入锁和Condition.

    final ReentrantLock lock;
    private final Condition notEmpty;
    private final Condition notFull;
    take()过程:
    public E take() throws InterruptException{
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try{
        while(count==0)
            notEmpty.await();
        return extract();
        }
    finally{
        lock.unlock();
    }}
    当队列为空时,要求当前线程等待,当队列中有新元素时,该线程会得到一个通知,继续执行
    private void insert(E x){
        items[putIndex] = x;
        putIndex = inc(putIndex);
        ++count;
        notEmpty.signal();
    }
    新元素入队后,通知等待在notEmpty上的线程,让他们继续执行。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值