码迷,mamicode.com
首页 > 编程语言 > 详细

java中并发包里面的内容

时间:2018-03-06 11:28:54      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:并发

java中的并发包里面的内容

1、CyclicBarrier

一个同步辅助类,允许一组线程相互等待,直到这组线程都到达某个公共屏障点。该barrier在释放等待线程后可以重用,因此称为循环的barrier。

来个示例:

  • package test;  


  • import java.util.concurrent.CyclicBarrier;  

  • import java.util.concurrent.ExecutorService;  

  • import java.util.concurrent.Executors;  


  • public class Recipes_CyclicBarrier {  

  • public static CyclicBarrier barrier = new CyclicBarrier(10);  


  • public static void main(String[] args){  

  • ExecutorService executor = Executors.newCachedThreadPool();//FixedThreadPool(10);  

  • for(int i=1;i<=10;i++){  

  • executor.submit(new Thread(new Runner(i+"号选手")));  

  • }  

  • executor.shutdown();  

  • }  

  • }  


  • class Runner implements Runnable{  

  • private String name;  


  • public Runner(String name){  

  • this.name = name;  

  • }  


  • @Override  

  • public void run() {  

  • System.out.println(name + "准备好了。");  

  • try {  

  • Recipes_CyclicBarrier.barrier.await();  //此处就是公共屏障点,所有线程到达之后,会释放所有等待的线程  

  • } catch (Exception e) {  

  • }  

  • System.out.println(name + "起跑!");  

  • }  

  • }  

  • 2、CountDownLatch

    CountDownLatch和CyclicBarrier有点类似,但是还是有些区别的。CountDownLatch也是一个同步辅助类,它允许一个或者多个线程一直等待,直到正在其他线程中执行的操作完成。它是等待正在其他线程中执行的操作,并不是线程之间相互等待。CountDownLatch初始化时需要给定一个计数值,每个线程执行完之后,必须调用countDown()方法使计数值减1,直到计数值为0,此时等待的线程才会释放。

    来个示例:

    [java] view plain copy

  • package test;  


  • import java.util.concurrent.CountDownLatch;  

  • import java.util.concurrent.CyclicBarrier;  

  • import java.util.concurrent.ExecutorService;  

  • import java.util.concurrent.Executors;  


  • public class CountDownLatchDemo {  

  • public static CountDownLatch countDownLatch = new CountDownLatch(10);//初始化计数值  


  • public static void main(String[] args){  

  • ExecutorService executor = Executors.newCachedThreadPool();//FixedThreadPool(10);  

  • for(int i=1;i<=10;i++){  

  • executor.submit(new Thread(new Runner1(i+"号选手")));  

  • }  

  • executor.shutdown();  

  • }  

  • }  


  • class Runner1 implements Runnable{  

  • private String name;  


  • public Runner1(String name){  

  • this.name = name;  

  • }  


  • @Override  

  • public void run() {  

  • System.out.println(name + "准备好了。");  

  • CountDownLatchDemo.countDownLatch.countDown();  //计数值减1  

  • try {  

  • CountDownLatchDemo.countDownLatch.await();  

  • } catch (Exception e) {  

  • }  

  • System.out.println(name + "起跑!");  

  • }  

  • }  

  • 3、CopyOnWriteArrayList & CopyOnWriteArraySet

    CopyOnWriteArrayList & CopyOnWriteArraySet是并发容器,适合读多写少的场景,如网站的黑白名单设置。缺点是内存占用大,数据一致性的问题,CopyOnWrite容器只能保证数据最终的一致性,不能保证数据实时一致性。鉴于它的这些缺点,可以使用ConcurrentHashMap容器。

    实现原理:新增到容器的数据会放到一个新的容器中,然后将原容器的引用指向新容器,旧容器也会存在,因此会有两个容器占用内存。我们也可以用同样的方式实现自己的CopyOnWriteMap。

    4、ConcurrentHashMap

    ConcurrentHashMap同样是一个并发容器,将同步粒度最小化。

    实现原理:ConcurrentHashMap默认是由16个Segment组成,每个Segment由多个Hashtable组成,数据变更需要经过两次哈希算法,第一次哈希定位到Segment,第二次哈希定位到Segment下的Hashtable,容器只会将单个Segment锁住,然后操作Segment下的Hashtable,多个Segment之间不受影响。如果需要扩容不是对Segment扩容而是对Segment下的Hashtable扩容。虽然经过两次哈希算法会使效率降低,但是比锁住整个容器效率要高得多。

    5、BlockingQueue

    BlockingQueue只是一个接口,它的实现类有ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、DelayQueue、LinkedBlockingDeque。

    ArrayBlockingQueue:由数据支持的有界阻塞队列。

    LinkedBlockingQueue:基于链接节点、范围任意的阻塞队列。

    PriorityBlockingQueue:无界阻塞队列。

    SynchronousQueue:一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作。

    DelayQueue:Delayed元素的一个无界阻塞队列。

    LinkedBlockingDeque:基于链接节点、范围任意的双端阻塞队列,可以在队列的两端添加、移除元素。

    6、Lock

    Lock分为公平锁和非公平锁,默认是非公平锁。实现类有ReetrantLock、ReetrantReadWriteLock,都依赖于AbstractQueuedSynchronizer抽象类。ReetrantLock将所有Lock接口的操作都委派到Sync类上,Sync有两个子类:NonFairSync和FaiSync,通过其命名就能知道分别处理非公平锁和公平锁的。AbstractQueuedSynchronizer把所有请求构成一个CLH队列,这里是一个虚拟队列,当有线程竞争锁时,该线程会首先尝试是否能获取锁,这种做法对于在队列中等待的线程来说是非公平的,如果有线程正在Running,那么通过循环的CAS操作将此线程增加到队尾,直至添加成功。

    7、Atomic包

    Atomic包下的类实现了原子操作,有对基本类型如int、long、boolean实现原子操作的类:AtomicInteger、AtomicLong、AtomicBoolean,如果需要对一个对象进行原子操作,也有对对象引用进行原子操作的AtomicReference类,还有对对象数组操作的原子类:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray。原子操作核心思想是CAS操作,然后调用底层操作系统指令来实现。



java中并发包里面的内容

标签:并发

原文地址:http://blog.51cto.com/13552251/2083327

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!