您的位置:首页 > 产品设计 > UI/UE

java并发容器(Map、List、BlockingQueue)

2017-07-01 15:53 429 查看
早期同步容器问题
Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable。另外还有JDK1.2中加入的同步包装类,这些类都是由Collections.synchronizedXXX工厂方法。同步容器都是线程安全的,但是对于复合操作,还有些缺点:① 迭代:在查觉到容器在迭代开始以后被修改,会抛出一个未检查异常ConcurrentModificationException,为了避免这个异常,需要在迭代期间,持有一个容器锁。但是锁的缺点也很明显,就是对性能的影响。② 隐藏迭代器:StringBuilder的toString方法会通过迭代容器中的每个元素,另外容器的hashCode和equals方法也会间接地调用迭代。类似地,contailAll、removeAll、retainAll方法,以及容器作为参数的构造函数,都会对容器进行迭代。③ 缺少即加入等一些复合操作[code=java;toolbar:false">public static Object getLast(Vector list) {         int lastIndex = list.size() - 1;         return list.get(lastIndex);}public static void deleteLast(Vector list) {         int lastIndex = list.size() - 1;         list.remove(lastIndex);}if(map.containsKey(key) && map.get(key).equals(value)){    Map.remove();    return true;}else{    return false;}queue=new PriorityQueue();queue.offer("testone");queue.offer("testtwo");queue.offer("testthree");queue.offer("testfour");System.out.println(queue.poll());

2.3 ConcurrentLinkedQueue

基于链节点的,线程安全的队列。并发访问不需要同步。在队列的尾部添加元素,并在头部删除他们。所以只要不需要知道队列的大小,并发队列就是比较好的选择。

3 阻塞队列

3.1 生产者和消费者模式

BlockingQueue<String> queue=new ArrayBlockingQueue<String>(5); Producer p=new Producer(queue);Consumer c1=new Consumer(queue);Consumer c2=new Consumer(queue); new Thread(p).start();new Thread(c1).start();new Thread(c2).start(); /** * 生产者 * @author Administrator * */class Producer implements Runnable {   private final BlockingQueue queue;   Producer(BlockingQueue q) { queue = q; }      public void run() {     try {          for(int i=0;i<100;i++){              queue.put(produce());          }           } catch (InterruptedException ex) {}   }      String produce() {       String temp=""+(char)('A'+(int)(Math.random()*26));       System.out.println("produce"+temp);       return temp;   } } /** * 消费者 * @author Administrator * */class Consumer implements Runnable {   private final BlockingQueue queue;   Consumer(BlockingQueue q) { queue = q; }   public void run() {     try {      for(int i=0;i<100;i++){          consume(queue.take());      }     } catch (InterruptedException ex) {}   }   void consume(Object x) {       System.out.println("cousume"+x.toString());   } } 输出:produceKcousumeKproduceVcousumeVproduceQcousumeQproduceIproduceDproduceIproduceGproduceAproduceEcousumeD

3.3 PriorityBlockingQueue

一个按优先级堆支持的无界优先级队列,如果不希望按照HashMap cache=new HashMap();public synchronized V compute(A arg){    V result=cace.get(arg);    if(result==null){        result=c.compute(arg);        cache.put(result);    }    return result;}2.用Map<A,FutureTask<V>> cache=new ConcurrentHashMap<A,FutureTask<V>>();public  V compute(A arg){    FutureTask <T> f=cace.get(arg);    //检查再运行的缺陷    if(f==null){        Callable<V> evel=new Callable(){            Public V call() throws ..{                return c.compute(arg);            }        };        FutureTask <T> ft=new FutureTask<T>(evel);        f=ft;        cache.put(arg,ft;        ft.run();    }    Try{        //阻塞,直到完成        return f.get();    }cach(){    }}4.上面还有检查再运行的缺陷,在高并发的情况下啊,双方都没发现FutureTask
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: