java并发编程基础--容器与LinkedBlockingQueue介绍

一、同步容器与并发容器

1、同步容器

1)类型 :Vector、HashTable--JDK提供的同步容器类

      Collections.synchronizedXXX 本质是对相应的容器进行包装

2)缺点:单独使用里面的方法时是线程安全的,但是在复合操作中则需添加额外的锁来保证线程安全

(如在Iterator迭代容器或for-each遍历容器中,需在迭代过程持有容器的锁,但容器较大时,又会降低性能;或者使用“克隆”容器的方式,使用线程封闭,但在创建副本的时候也会降低性能)

3)示例:往同步容器中添加1000个元素,开启4个线程,删除其中其中一个元素

public class VectorDemo {

    public static void main(String[] args) {
        Vector<String> stringVector = new Vector<>();
        for (int i = 0; i < 1000; i++) {
            stringVector.add("demo" + i);
        }

        Iterator<String> stringIterator = stringVector.iterator();
        for (int i = 0; i < 4; i++) {
            new Thread(() -> {
                synchronized (stringIterator) {
                    while (stringIterator.hasNext()) {
                        String next = stringIterator.next();
                        if (next.equals("demo2")) {
                            stringIterator.remove();
                        }
                    }
                }
            }).start();
        }
    }

}

2、并发容器

      针对上面由于使用锁带来的并发访问性能问题,出现了并发容器,主要有这三大系列:CopyOnWrite\Concurrent\BlockingQueue

示例:同样是往并发容器中添加1000个元素,开启4个线程,删除其中一个元素

public class demo {

    public static void main(String[] args) {
        CopyOnWriteArrayList<String> strings = new CopyOnWriteArrayList<>();
        for(int i=0;i<1000;i++){
            strings.add("demo"+i);
        }
        for (int i =0;i<4;i++){
            new Thread(()->{
                strings.forEach(e->{
                    if (e.equals("demo2")){
                        strings.remove(e);
                    }
                });
            }).start();
        }
    }

}

二、LinkedBlockingQueue的使用

在并发编程中,LinkedBlockingQueue使用的非常频繁。因其可以作为生产者消费者的中间商

            add  实际上调用的是offer,区别是在队列满的时候,add会报异常
            offer  对列如果满了,直接入队失败
            put(); 在队列满的时候,会进入阻塞的状态

            
            remove(); 直接调用poll,唯一的区别即使remove会抛出异常,而poll在队列为空的时候直接返回null
            poll(); 在队列为空的时候直接返回null
            take(); 在队列为空的时候,会进入等待的状态

public class Demo2 {
    public static void main(String[] args) throws InterruptedException {
        LinkedBlockingQueue<String> strings = new LinkedBlockingQueue<>();
        //往队列里存元素
        strings.add("111");
        strings.offer("111");
        strings.put("111");

        //从队列中取元素
        String remove = strings.remove();
        strings.poll();
        strings.take();

    }
}

猜你喜欢

转载自blog.csdn.net/qq_38966361/article/details/87941203