zoukankan      html  css  js  c++  java
  • Java多线程同步集合--并发库高级应用

    一、阻塞队列
    1、在多线程领域,所谓阻塞,在某些情况下会挂起线程,一旦条件满足,被挂起的线程又会自动被唤醒
    2、ArrayBlockingQueue(效率高)和LinkedBlockingQueue是两个最常用的阻塞队列,一般情况下用来处理多线程间的生产者消费者问题。

    二、并发队列
    ConcurrentLinkedQueue

    传统方式下用Collections工具类提供的synchronizedCollection方法来获得同步集合。

    三、同步集合类
    java5中还提供了如下一些同步集合类:
    > java.util.concurrent - Java并发工具包
    > ConcurrentHashMap 进行HashMap的并发操作,用来替代Collections.synchronizedMap(m)方法。
    > ConcurrentSkipListMap 实现了SortedMap<K,V>,类似于TreeMap
    > ConcurrentSkipListSet 实现了SortedSet, 类似于TreeSet
    > CopyOnWriteArrayList
    > CopyOnWriteArraySet
    注:CopyOnWriteArrayList和CopyOnWriteArraySet,最适合于读操作通常大大超过写操作的情况。

    传统方式下Collection在迭代时,不允许对集合进行修改,使用Iterator对集合进行迭代时也不能修改集合;其中CopyOnWriteArrayList在遍历的时候修改是不会出错的,实现方法是读写分离。

    四、ReentrantLock
    Condition实现线程间的通信,类似在线程中的Object.wait()和Object.notify()
    eg、 private Lock lock = new ReentrantLock(); // 账户锁
    private Condition _save = lock.newCondition(); // 存款条件
    private Condition _draw = lock.newCondition(); // 取款条件

    五、ReadWriteLock--实现读写锁
    eg、private ReadWriteLock rwl = new ReentrantReadWriteLock();
    rwl.readLock();
    rwl.writeLock();


    六、线程池,5种
    缓存线程池、固定大小线程池、调度线程池、单例线程池、自定义线程池(参数:线程数、最大线程数、空闲时间、时间单位、队列)

    七、生产消费模式
    并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue、ArrayBlockingQueue

    八、synchronized锁和ReentrantLock锁的区别

    synchronized是在JVM层面上实现的,可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中

    在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;

    九、CountDownLatch、CyclicBarrier(同步屏障)、信号灯区别

    1、CyclicBarrier 多个线程相互等待,直到所有的线程都完成,如果他们之间任何一个线程没有完成,所有的线程都必须等待。
    eg、await()、getNumberWaiting()

    2、CountDownLatch 控制多个线程的执行顺序,调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值countDown()减到0为止。
    eg、有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。

     

    3、Semaphore 信号灯,场景:停车场运作、限流
    假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。

    // 获取许可
    semp.acquire();
    ...
    // 访问完后,释放
    semp.release();


  • 相关阅读:
    SpringMVC配置双数据源,一个java项目同时连接两个数据库
    Jquery EasyUI封装简化操作
    C#中Math.Round()实现中国式四舍五入
    Entity Framework6 with Oracle
    在C#中如何读取枚举值的描述属性
    MVC视图中处理Json
    ASP.NET MVC中实现多个按钮提交的几种方法
    asp.net MVC的EF与easyui DataGrid数据绑定
    idea maven下载包太慢了如何解决
    ssh报错No operations allowed after connection closed.Connection was implicitly clos
  • 原文地址:https://www.cnblogs.com/linjiqin/p/6451504.html
Copyright © 2011-2022 走看看