Queue

来源:互联网 发布:javascript计算器代码 编辑:程序博客网 时间:2024/05/16 17:53

关于同步类容器和并发类容器,高性能ConcurrentLinkedQueue,阻塞式BlockingQueue接口的一些实现,例如ArrayBlockQueue,LinkedBlockingQueue,SynchronousQueue,PriorityBlockingQueue,DelayQueue的实现及一些应用场景

1.关于同步类容器和并发类容器

[java] view plain copy
  1. package com.wpx.thread.demo04;  
  2.   
  3. import java.util.Map;  
  4. import java.util.concurrent.ConcurrentHashMap;  
  5. import java.util.concurrent.CopyOnWriteArrayList;  
  6. import java.util.concurrent.CopyOnWriteArraySet;  
  7.   
  8. /** 
  9.  * 同步类容器:如Vector,Has和Table这些容器的同步功能其实都是JDK的Collections,synchronized等工厂方法创建实现 
  10.  *  
  11.  * 同步类容器都是线程安全的,但某些场景下需要加锁俩保护复合操作 
  12.  * 如:迭代(反复访问元素,遍历完容器中的所有元素) 
  13.  * 跳转(根据当前元素按照特定顺序去查找下一个元素) 
  14.  *  
  15.  * 因为同步类容器通过大量使用synchronized关键字,通过锁的方式使得只有一个线程可以操作数据 
  16.  * 同步类容器都是串行化的,他们虽然实现了线程安全,但是严重降低了并发性,在多线程环境下,严重降低了应用程序的吞吐量 
  17.  * 为解决这些问题jdk提供了多种并发类容器来替代同步类容器从而改善性能 
  18.  *  
  19.  * 使用ConcurrentHashMap 来代替给予散列的传统的HashTable 
  20.  * 以及使用CopyOnWriterArrayList代替Voctor 
  21.  * 并发的CopyonWriterAr raySet 
  22.  * 以及并发的Queue,高性能的队列ConcurrentLinkedQueue,阻塞式的队列LinkedBlockingQueue 
  23.  * 具体实现Queue还有ArrayBlockQueue,PriorityBlockingQueue,SynchronizedQueue等 
  24.  *  
  25.  *  
  26.  * ConcurrentMap接口有两个重要的实现 
  27.  * ConcurrentHashMap 
  28.  * ConcurrentSkipListMap (支持并发排序功能,弥补ConcurrentMapHashMap) 
  29.  *  
  30.  * ConcurrentHashMap内部使用断来表示这些不同的部分,每个段其实就是一个小的HashTale他们有自己的锁 
  31.  * 只要多个修改操作发生在不同的段上,他们就可以并发的记性,把一个整体分成了16个段,也就是最高支持16个线程的并发修改操作 
  32.  * 这也是在多线程场景时减少锁粒度从而降低锁竞争的一种方案,将大多共享变量使用volatile关键字声明,进而实时的获得修改的内容 
  33.  *  
  34.  * 对于CopyOnWriter容器便是一个即写时复制 
  35.  * 在对容器元素进行修改时,不直接在当前容器修改,而是将当前容器进行复制,在新的容器中进行修改,在修改完成后,将原容器的引用执向新的容器 
  36.  * 好处是我们可以对CopyOnWriter容器进行并发的读,而不需要加锁,即COW是一种读写分离的容器 
  37.  * 应用场景:读多写少 
  38.  *  
  39.  *  
  40.  * @author wangpx 
  41.  */  
  42. public class demo01 {  
  43.     public static void main(String[] args) {  
  44.         ConcurrentHashMap<String,Object> map=new ConcurrentHashMap<String,Object>();  
  45.         map.put("k1""k1value");  
  46.         map.putIfAbsent("k1""k1值");  
  47.         for (Map.Entry<String, Object> m : map.entrySet()) {  
  48.             System.out.println("Key:" +m.getKey()+" : "+m.getValue());  
  49.         }  
  50.           
  51.         CopyOnWriteArraySet<String> s=new CopyOnWriteArraySet<String>();  
  52.         CopyOnWriteArrayList<String> list=new CopyOnWriteArrayList<>();  
  53.   
  54.           
  55.     }  
  56. }  
2.ConcurrentLinkedQueue
[java] view plain copy
  1. package com.wpx.thread.demo04;  
  2.   
  3. import java.util.concurrent.ConcurrentLinkedQueue;  
  4.   
  5. /** 
  6.  * ConcurrentLinkedQueue: 
  7.  * 适用于高并发场景下的队列,通过无锁的方式,实现了高并发状态下的高性能,通常情况下ConcurrentQuueu性能好于BlockingQueue 
  8.  * 他是一个基于链接节点的无界线程安全队列,该队列的元素遵循先进先出的原则,该队列不允许null元素 
  9.  *  
  10.  * ConcurrentLinkedQueue的重要方法 
  11.  * add()和offer()都是加入元素的方法,zaiConcurrentLinkedQueue中这两个方法没有区别 
  12.  * poll()和peek()都是取头元素节点,区别在于前者会删除元素,后者不会 
  13.  *  
  14.  * @author wangpx 
  15.  */  
  16. public class demo02 {  
  17.     public static void main(String[] args) {  
  18.     ConcurrentLinkedQueue<String> queue=new ConcurrentLinkedQueue<String>();  
  19.     queue.add("1");  
  20.     queue.add("2");  
  21.     System.out.println(queue.poll());;  
  22.     System.out.println(queue.size());  
  23.     System.out.println(queue.peek());  
  24.     System.out.println(queue.size());  
  25. }  
  26.           
  27. }  
3.ArrayBlockQueue

[java] view plain copy
  1. package com.wpx.thread.demo04;  
  2.   
  3. import java.util.concurrent.ArrayBlockingQueue;  
  4. import java.util.concurrent.TimeUnit;  
  5.   
  6. /** 
  7.  *  
  8.  * BlockingQueue接口 
  9.  *  
  10.  *  ArrayBlockQueue:基于数组的阻塞队列实现,在ArrayBlockQueue内部,维护了一个定长的数组, 
  11.  * 便于缓存队列中的数据对象,,其内部没有实现读写分离,也就意味着生产和消费不能完全并行,长度需要定义, 
  12.  * 可以指定先进先出或者先进后出,也叫有界队列 
  13.   
  14.  
  15.  *  
  16.  * @author wangpx 
  17.  */  
  18. public class demo03 {  
  19.     public static void main(String[] args) throws Exception{  
  20.         /** 
  21.          * false 
  22.          * Exception in thread "main" java.lang.IllegalStateException: Queue full 
  23.             at java.util.AbstractQueue.add(AbstractQueue.java:98) 
  24.             at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312) 
  25.             at com.wpx.thread.demo04.demo03.main(demo03.java:41) 
  26.          *  
  27.          */  
  28.         ArrayBlockingQueue<String> array=new ArrayBlockingQueue<String>(3);  
  29.         array.add("a");  
  30.         array.add("b");  
  31.         array.add("c");  
  32.         System.out.println(array.offer("c"1, TimeUnit.SECONDS));  
  33.          array.add("d");  
  34.           
  35.     }  
  36. }  

4.LinkedBlockingQueue

[java] view plain copy
  1. package com.wpx.thread.demo04;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import java.util.concurrent.LinkedBlockingQueue;  
  6. import java.util.concurrent.TimeUnit;  
  7.   
  8. /** 
  9.  * LinkedBlockingQueue:基于链表的阻塞队列,,同ArrayBlockingQueue类似,其内部也维持着一个数据缓冲队列 
  10.  * 队列由数据缓冲队列,队列由一个链表构成,LinkedBlockingQueue之所以能高效的处理并发数据是因为其内部采用分离锁 
  11.  * 从而实现生产者和消费者的完全并行处理,他是一个无界队列 
  12.  * @author wangpx 
  13.  */  
  14. public class demo04 {  
  15.   
  16.     /** 
  17.      * true 
  18.         drainTo方法 批量去数据 
  19.         ab 
  20.      * @param args 
  21.      * @throws Exception 
  22.      */  
  23.     public static void main(String[] args) throws Exception{  
  24.     LinkedBlockingQueue<String> queue =new LinkedBlockingQueue<String>();  
  25.     queue.add("a");  
  26.     queue.add("b");  
  27.     queue.add("c");  
  28.     System.out.println(queue.offer("d"1, TimeUnit.SECONDS));  
  29.     queue.add("e");  
  30.     List<String> list=new ArrayList<>();  
  31.     queue.drainTo(list, 2);  
  32.     list.stream().forEach(System.out::print);  
  33.       
  34. }  
  35. }  
5.Synchronous
[java] view plain copy
  1. package com.wpx.thread.demo04;  
  2.   
  3. import java.util.concurrent.SynchronousQueue;  
  4.   
  5. /** 
  6.  * SynchronousQueue:一种没有缓冲的队列,生产者生产的数据直接会被消费者获取并消费 
  7.  * 这个队列没有容量 
  8.  * @author wangpx 
  9.  */  
  10. public class demo05 {  
  11.   
  12.     public static void main(String[] args) {  
  13.          SynchronousQueue<String> queue=new  SynchronousQueue<>();  
  14.         /** 
  15.          * Exception in thread "main" java.lang.IllegalStateException: Queue full 
  16.             at java.util.AbstractQueue.add(AbstractQueue.java:98) 
  17.             at com.wpx.thread.demo04.demo05.main(demo05.java:13) 
  18.          */  
  19.             queue.add("a");  
  20.     }  
  21. }  

6.DelayQueue

[java] view plain copy
  1. package com.wpx.thread.demo04;  
  2.   
  3. import java.util.concurrent.DelayQueue;  
  4. import java.util.concurrent.Delayed;  
  5. import java.util.concurrent.TimeUnit;  
  6. /** 
  7.  *  
  8.     DelayQueue带有延迟时间的Queue,其中的元素只有当指定的延迟时间到了,才能够从队列中获取到该元素 
  9.     DelayQueue中的元素必须实现Dalayed接口 
  10.     DelayQueue没有大小限制 
  11.     DelayQueue应用场景: 对缓存超时的数据移除,任务超时处理,空闲连接的关闭 
  12.      
  13.      
  14.      
  15.     网吧开始营业 
  16.     网名为:w身份证为:1996交钱1块,开始上级 
  17.     网名为:p身份证为:1995交钱5块,开始上级 
  18.     网名为:x身份证为:1994交钱3块,开始上级 
  19.     网名为:w身份证为:1996下机了 
  20.     网名为:x身份证为:1994下机了 
  21.     网名为:p身份证为:1995下机了 
  22.  * @author wangpx 
  23.  */  
  24. public class WangBa implements Runnable{  
  25.     private DelayQueue<WangMin> queue=new DelayQueue<WangMin>();  
  26.     public boolean yingye=true;  
  27.     public void shangji(String name,Integer id,int money) {  
  28.         WangMin wangmin=new WangMin(id, name, 1000*money+System.currentTimeMillis());  
  29.         System.out.println("网名为:"+wangmin.getName()+"身份证为:"+wangmin.getId()+"交钱"+money+"块,开始上级");  
  30.         this.queue.add(wangmin);  
  31.     }  
  32.     public void xiaji(WangMin wangmin) {  
  33.         System.out.println("网名为:"+wangmin.getName()+"身份证为:"+wangmin.getId()+"下机了");  
  34.     }  
  35.     @Override  
  36.     public void run() {  
  37.      while(yingye) {  
  38.          try {  
  39.             WangMin w=queue.take();  
  40.             xiaji(w);  
  41.          } catch (InterruptedException e) {   
  42.             e.printStackTrace();  
  43.         }  
  44.      }    
  45.           
  46.     }  
  47.     public static void main(String[] args) {  
  48.         try {  
  49.             System.out.println("网吧开始营业");  
  50.             WangBa w=new WangBa();  
  51.             Thread shangnwang=new Thread(w);  
  52.             shangnwang.start();  
  53.             w.shangji("w"19961);  
  54.             w.shangji("p"19955);  
  55.             w.shangji("x"19943);  
  56.               
  57.               
  58.         } catch (Exception e) {  
  59.             e.printStackTrace();  
  60.         }  
  61.     }  
  62. }  
  63. class WangMin implements Delayed{  
  64.   
  65.     private Integer id;  
  66.     private String name;  
  67.     private long endTime;  
  68.     private TimeUnit timeUnit=TimeUnit.SECONDS;  
  69.       
  70.     public WangMin() {  
  71.   
  72.     }  
  73.   
  74.     public WangMin(Integer id, String name, long endTime) {  
  75.         super();  
  76.         this.id = id;  
  77.         this.name = name;  
  78.         this.endTime = endTime;  
  79.     }  
  80.   
  81.     public Integer getId() {  
  82.         return id;  
  83.     }  
  84.     public String getName() {  
  85.         return name;  
  86.     }  
  87.   
  88.     @Override  
  89.     public int compareTo(Delayed delayed) {  
  90.         WangMin wangMin=(WangMin) delayed;  
  91.         return this.getDelay(this.timeUnit) -wangMin.getDelay(this.timeUnit)> 0 ? 10;  
  92.     }  
  93.   
  94.     @Override  
  95.     public long getDelay(TimeUnit unit) {  
  96.    
  97.         return endTime - System.currentTimeMillis();  
  98.     }  
  99.       
  100. }  
7.PriorityBlockingQueue

[java] view plain copy
  1. package com.wpx.thread.demo04;  
  2.   
  3. import java.util.concurrent.PriorityBlockingQueue;  
  4.   
  5. /** 
  6.  * PriorityBlockingQueue:基于优先级的阻塞队列,优先级的判断通过函数传入的Compator对象来决定, 
  7.  * 也就是说传入队列的对象必须实现Comparable接口 
  8.  * 在实现PriorityBlockingQueue时,内部控制线程同步的锁采用的是公平锁,他是一个无界的队列 
  9.  * @author wangpx 
  10.  */  
  11. public class demo07 {  
  12.   
  13.     /** 
  14.         wapx1 
  15.         wpx5 
  16.         wpx15 
  17.         wpx8 
  18.         wpx27 
  19.         ------------------ 
  20.         wapx1 
  21.         wpx5 
  22.         wpx8 
  23.         wpx15 
  24.         wpx27 
  25.         底层选出一个优先级最高的,一个take一次比较 
  26.      * @param args 
  27.      */  
  28.     public static void main(String[] args) throws Exception{  
  29.         PriorityBlockingQueue<Student> queue=new PriorityBlockingQueue<Student>();  
  30.         Student s1=new Student(8"wpx8");  
  31.         Student s2=new Student(1"wapx1");  
  32.         Student s3=new Student(15"wpx15");  
  33.         Student s4=new Student(5"wpx5");  
  34.         Student s5=new Student(27"wpx27");  
  35.         queue.add(s1);  
  36.         queue.add(s2);  
  37.         queue.add(s3);  
  38.         queue.add(s4);  
  39.         queue.add(s5);  
  40.         queue.stream()  
  41.              .map((e)-> e.getName())  
  42.              .forEach(System.out::println);  
  43.         System.out.println("------------------");  
  44.         int size = queue.size();  
  45.         for(int i=0;i<size;i++) {  
  46.             System.out.println(queue.take().getName());  
  47.         }  
  48.       
  49.           
  50.           
  51.   
  52.           
  53. }  
  54. }  
  55. class Student implements Comparable<Student>{  
  56.     private Integer id;  
  57.     private String name;  
  58.     public Integer getId() {  
  59.         return id;  
  60.     }   
  61.     public void setId(Integer id) {  
  62.         this.id = id;  
  63.     }  
  64.     public String getName() {  
  65.         return name;  
  66.     }  
  67.     public void setName(String name) {  
  68.         this.name = name;  
  69.     }  
  70.       
  71.     public Student() {  
  72.   
  73.     }  
  74.     public Student(Integer id, String name) {  
  75.         this.id = id;  
  76.         this.name = name;  
  77.     }  
  78.     @Override  
  79.     public int compareTo(Student student) {  
  80.       
  81.         return this.id>student.id ? 1: (this.id<student.id ? -1 :0);  
  82.     }  
  83.       
  84.       
  85. }  
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 王者传奇冲元宝不到账怎么办 支付宝充值地下城点卷冲错了怎么办 dnf点券冲错了怎么办 百家号改了手机绑定找不到了怎么办 银行卡换了网银怎么办 qq没有银行卡转不出钱怎么办 qq钱包限制一万怎么办 qq余额超过20万怎么办 扣扣忘记了密码怎么办 qq钱包发不出来怎么办 qq支付密码忘了怎么办? 扣扣上转账错了怎么办 qq绑卡存在异常怎么办 微信没绑银行卡忘记支付密码怎么办 微信的自动扣费怎么办 不小心把钱充到微信财付通该怎么办 财付通用什么充值卡充值话费怎么办 苹果手机灯坏了怎么办 手机电灯不亮了怎么办? 苹果手机相机坏了怎么办 苹果5s手机背光灯不亮怎么办 苹果5s灯控坏了怎么办 微信q币冲错号码怎么办 支付宝转账到之前号码怎么办 qq红包收不了钱怎么办 qq抢红包要实名认证怎么办 支付宝被骗冲q币怎么办 qq发红包发错了怎么办 qq红包发不出来怎么办 qq红包发多了怎么办 qq发红包要短信验证怎么办 不是qq好友发了红包怎么办 苹果手机升级后支付宝打不开怎么办 qqq币充了没进帐怎么办 怎么办q币换成qq余额 支付宝qb冲多了怎么办 微信没钱怎么办怎么赚 忘记微信支付密码怎么办 手机设备注册达上限怎么办 在新手机上登微信需要验证怎么办 手机号被限制注册qq号怎么办