精华内容
下载资源
问答
  • 你好,我是看山。...Vector虽然种种问题,但是都属于设计上的问题,为什么不在后续版本中进行优化呢?HashMap就优化了好几次。而SynchronizedList这个内部类(也就是通过Collections.synchronizedList(new A.

    Java 中 Vector 和 SynchronizedList 的区别

    你好,我是看山。

    本文还是折腾 Java 中的队列,上次比较了 Vector、ArrayList、CopyOnWriteArrayList、SynchronizedList,当时感觉挺明白,后来想想又有些不理解的地方,所以今天在重新翻出来研究一下,我承认我钻了牛角尖了。

    Vector虽然种种问题,但是都属于设计上的问题,为什么不在后续版本中进行优化呢?HashMap就优化了好几次。而SynchronizedList这个内部类(也就是通过Collections.synchronizedList(new ArrayList())创建的),也是采用了和Vector类似的同步方式(区别是一个在方法体、一个在方法块上,差别不大),为什么大家还是舍弃Vector呢?

    其实,在 JDK 中,Vector一直没有被标记为Deprecated,也就是说,虽然外界传说Vector有各种问题,但是从 JDK 官方,从没有认为这个亲儿子没用。

    所以,大家不用Vector的原因就剩下两种:

    1. 其他队列比Vector更加适合,优中选优
    2. 大家都说Vector不好用,那我也不用了【个人感觉这种概率更大】

    因为Vector主要是数组结构,所以下面大部分的对比都是比较的是针对ArrayList的同步封装。

    有了Vector为什么还要有SynchronizedList

    这个问题的答案是从 StackOverflow 中找到的。

    在 JDK 1.2 之前,Collections是独立类库,不是 JDK/JRE 中的一部分。当时synchronized性能特别差,很多场景不需要使用同步方式,所以,独立类库的开发者删除了同步操作,这个应该就是ArrayList的前身。但是,少部分场景还是需要使用同步,于是就有了SynchronizedList,一个可以包装所有List子类的包装类,这个类在几乎所有方法上都加上了synchronized同步,这个设计与Vector相似。

    古人说“文人相轻”,其实在编码界也是有鄙视链的。在这里就是:虽然我的设计和你的设计类似,但是我的设计就是比你的好。不过,Collections确实设计更优。

    一个SynchronizedList实现所有List的同步

    SynchronizedList定位是包装类,可以包装所有List的子类。也就是说,无论是ArrayList还是LinkedList都能过实现同步,完全不会修改底层数据结构,既实现的同步,又保留了底层接口的优点。比如LinkedList的插入、删除效率,ArrayList的顺序读取。而且,一个包装类就解决所有List子类的同步需求,完全不需要重复实现一遍。

    相对而言,Vector就比较霸道了,任何想要同步的队列,都需要转换为Vector的数组结构。大家都知道,数组存储需要连续空间,顺序读取效率表现优秀,但是插入和删除效率就比较差了。

    将迭代器的同步权利交给用户

    同步方法中SynchronizedListVector很类似,不过迭代器方法有了不同想法。

    看源码就知道,SynchronizedList中的iteratorlistIterator方法都没有实现同步,所以在获取迭代器的时候不会阻塞。

    public Iterator<E> iterator() {
        return list.iterator(); // Must be manually synched by user!
    }
    
    public ListIterator<E> listIterator() {
        return list.listIterator(); // Must be manually synched by user
    }
    
    public ListIterator<E> listIterator(int index) {
        return list.listIterator(index); // Must be manually synched by user
    }
    

    如果需要迭代的话,直接用synchronized包一下队列对象就可以了,代码如下:

    final List<String> list = Collections.synchronizedList(new ArrayList());
    list.add("A");
    list.add("B");
    list.add("C");
    final Iterator<String> iterator = list.iterator();
    
    synchronized (list) {
        while (iterator.hasNext()) {
            final String next = iterator.next();
            System.out.println(next);
        }
    }
    

    我们再看下Vector迭代器实现:

    /**
        * An optimized version of AbstractList.Itr
        */
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;
    
        public boolean hasNext() {
            // Racy but within spec, since modifications are checked
            // within or after synchronization in next/previous
            return cursor != elementCount;
        }
    
        public E next() {
            synchronized (Vector.this) {
                checkForComodification();
                int i = cursor;
                if (i >= elementCount)
                    throw new NoSuchElementException();
                cursor = i + 1;
                return elementData(lastRet = i);
            }
        }
    
        public void remove() {
            if (lastRet == -1)
                throw new IllegalStateException();
            synchronized (Vector.this) {
                checkForComodification();
                Vector.this.remove(lastRet);
                expectedModCount = modCount;
            }
            cursor = lastRet;
            lastRet = -1;
        }
    
        // 此处省略一些方法
    }
    

    Vector的迭代器用synchronized (Vector.this)加锁,其实也是对当前类实例加锁,和我们自己实现的加锁方式一致。当然,从这点上来说,Vector能够保证在开发人员无意识的情况下,避免为同步造成的错误,这也是Vector的一个优点。

    Vector不完全一无是处

    虽然Vector在其他地方败给了Collections,但是在扩容这方面,还有一个可取之处。先看看Vector的扩容方法:

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                            capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    

    在计算新数组长度的时候,会检查capacityIncrement是否大于 0,如果是,就扩容capacityIncrement的大小。就是说,在Vector中可以指定扩容大小,如果没有指定,默认扩容到原来的 2 倍;而ArrayList只能扩容到 1.5 倍,没有办法自定义扩容大小。

    仔细想想,这点并没有什么用处。

    文末总结

    1. Vector内部结构是数组,与Collections.synchronizedList(new ArrayList())类似。
    2. Vector可以指定扩容大小,默认是扩容到原数组长度的 2 倍;ArrayList不能指定扩容大小,直接扩容到原数组大小的 1.5 倍。
    3. SynchronizedList是一个包装类,可以将List子类都包装为同步队列,从非线程安全队列转为线程安全队列,没有性能延迟,直接包装即可;Vector是一个基于数组的同步队列,其他队列想要转换为Vector,需要有数据拷贝。
    4. SynchronizedList的迭代器没有做同步,需要用户自己实现;Vector的迭代器做好了同步,开发人员不需要关心同步。
    5. Vector至今未标记Deprecated,而且随着 JDK 发布,也在更新实现。虽然 JDK 承诺兼容,但是一直没有标记过期,其用意不得而知。

    推荐阅读

    1. 认识 Java 中的队列:Vector、ArrayList、CopyOnWriteArrayList、SynchronizedList
    2. 如果非要在多线程中使用 ArrayList 会发生什么?
    3. Why is Java Vector (and Stack) class considered obsolete or deprecated?
    4. In java, Vector and Collections.synchronizedList are all synchronized, what’s the difference?

    你好,我是看山,公众号:看山的小屋,10 年老猿,Apache Storm、WxJava、Cynomys 开源贡献者。游于码界,戏享人生。

    个人主页:https://www.howardliu.cn
    个人博文:Java 中 Vector 和 Collections.synchronizedList(new ArrayList()) 的区别
    CSDN 主页:http://blog.csdn.net/liuxinghao
    CSDN 博文:Java 中 Vector 和 Collections.synchronizedList(new ArrayList()) 的区别

    公众号:看山的小屋

    展开全文
  • Java并发编程:同步容器为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列、Synchronizer(比如CountDownLatch)。今天我们就来讨论下同步容器。以下是本文...

    Java并发编程:同步容器

    为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列、Synchronizer(比如CountDownLatch)。今天我们就来讨论下同步容器。

    以下是本文的目录大纲:

    一.为什么会出现同步容器?

    二.Java中的同步容器类

    三.同步容器的缺陷

    若有不正之处请多多谅解,并欢迎批评指正。

    请尊重作者劳动成果,转载请标明原文链接:

    http://www.cnblogs.com/dolphin0520/p/3933404.html

    一.为什么会出现同步容器?

    在Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map。

    List、Set、Queue接口分别继承了Collection接口,Map本身是一个接口。

    注意Collection和Map是一个顶层接口,而List、Set、Queue则继承了Collection接口,分别代表数组、集合和队列这三大类容器。

    像ArrayList、LinkedList都是实现了List接口,HashSet实现了Set接口,而Deque(双向队列,允许在队首、队尾进行入队和出队操作)继承了Queue接口,PriorityQueue实现了Queue接口。另外LinkedList(实际上是双向链表)实现了了Deque接口。

    像ArrayList、LinkedList、HashMap这些容器都是非线程安全的。

    如果有多个线程并发地访问这些容器时,就会出现问题。

    因此,在编写程序时,必须要求程序员手动地在任何访问到这些容器的地方进行同步处理,这样导致在使用这些容器的时候非常地不方便。

    所以,Java提供了同步容器供用户使用。

    二.Java中的同步容器类

    在Java中,同步容器主要包括2类:

    1)Vector、Stack、HashTable

    2)Collections类中提供的静态工厂方法创建的类

    Vector实现了List接口,Vector实际上就是一个数组,和ArrayList类似,但是Vector中的方法都是synchronized方法,即进行了同步措施。

    Stack也是一个同步容器,它的方法也用synchronized进行了同步,它实际上是继承于Vector类。

    HashTable实现了Map接口,它和HashMap很相似,但是HashTable进行了同步处理,而HashMap没有。

    Collections类是一个工具提供类,注意,它和Collection不同,Collection是一个顶层的接口。在Collections类中提供了大量的方法,比如对集合或者容器进行排序、查找等操作。最重要的是,在它里面提供了几个静态工厂方法来创建同步容器类,如下图所示:

    9b524ba74bd7aedcd2c42a8b1d865aa3.png

    三.同步容器的缺陷

    从同步容器的具体实现源码可知,同步容器中的方法采用了synchronized进行了同步,那么很显然,这必然会影响到执行性能,另外,同步容器就一定是真正地完全线程安全吗?不一定,这个在下面会讲到。

    我们首先来看一下传统的非同步容器和同步容器的性能差异,我们以ArrayList和Vector为例:

    1.性能问题

    我们先通过一个例子看一下Vector和ArrayList在插入数据时性能上的差异:

    public class Test {

    public static void main(String[] args) throws InterruptedException {

    ArrayList list = new ArrayList();

    Vector vector = new Vector();

    long start = System.currentTimeMillis();

    for(int i=0;i<100000;i++)

    list.add(i);

    long end = System.currentTimeMillis();

    System.out.println("ArrayList进行100000次插入操作耗时:"+(end-start)+"ms");

    start = System.currentTimeMillis();

    for(int i=0;i<100000;i++)

    vector.add(i);

    end = System.currentTimeMillis();

    System.out.println("Vector进行100000次插入操作耗时:"+(end-start)+"ms");

    }

    }

    这段代码在我机器上跑出来的结果是:

    11b51f595ef8de3421e6f9d5a7fbb3d7.png

    进行同样多的插入操作,Vector的耗时是ArrayList的两倍。

    这只是其中的一方面性能问题上的反映。

    另外,由于Vector中的add方法和get方法都进行了同步,因此,在有多个线程进行访问时,如果多个线程都只是进行读取操作,那么每个时刻就只能有一个线程进行读取,其他线程便只能等待,这些线程必须竞争同一把锁。

    因此为了解决同步容器的性能问题,在Java 1.5中提供了并发容器,位于java.util.concurrent目录下,并发容器的相关知识将在下一篇文章中讲述。

    2.同步容器真的是安全的吗?

    也有有人认为Vector中的方法都进行了同步处理,那么一定就是线程安全的,事实上这可不一定。看下面这段代码:

    public class Test {

    static Vector vector = new Vector();

    public static void main(String[] args) throws InterruptedException {

    while(true) {

    for(int i=0;i<10;i++)

    vector.add(i);

    Thread thread1 = new Thread(){

    public void run() {

    for(int i=0;i

    vector.remove(i);

    };

    };

    Thread thread2 = new Thread(){

    public void run() {

    for(int i=0;i

    vector.get(i);

    };

    };

    thread1.start();

    thread2.start();

    while(Thread.activeCount()>10){

    }

    }

    }

    }

    在我机器上运行的结果:

    8ec9e94b284c09287836ab6feb74911d.png

    正如大家所看到的,这段代码报错了:数组下标越界。

    也许有朋友会问:Vector是线程安全的,为什么还会报这个错?很简单,对于Vector,虽然能保证每一个时刻只能有一个线程访问它,但是不排除这种可能:

    当某个线程在某个时刻执行这句时:

    for(int i=0;i

    vector.get(i);

    假若此时vector的size方法返回的是10,i的值为9

    然后另外一个线程执行了这句:

    for(int i=0;i

    vector.remove(i);

    将下标为9的元素删除了。

    那么通过get方法访问下标为9的元素肯定就会出问题了。

    因此为了保证线程安全,必须在方法调用端做额外的同步措施,如下面所示:

    public class Test {

    static Vector vector = new Vector();

    public static void main(String[] args) throws InterruptedException {

    while(true) {

    for(int i=0;i<10;i++)

    vector.add(i);

    Thread thread1 = new Thread(){

    public void run() {

    synchronized (Test.class) { //进行额外的同步

    for(int i=0;i

    vector.remove(i);

    }

    };

    };

    Thread thread2 = new Thread(){

    public void run() {

    synchronized (Test.class) {

    for(int i=0;i

    vector.get(i);

    }

    };

    };

    thread1.start();

    thread2.start();

    while(Thread.activeCount()>10){

    }

    }

    }

    }

    3. ConcurrentModificationException异常

    在对Vector等容器并发地进行迭代修改时,会报ConcurrentModificationException异常,关于这个异常将会在后续文章中讲述。

    但是在并发容器中不会出现这个问题。

    参考资料:

    《深入理解Java虚拟机》

    《Java并发编程实战》

    展开全文
  • 为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列、Synchronizer(比如CountDownLatch)。今天我们就来讨论下同步容器。一.为什么会出现同步容器?在Java...

    为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列、Synchronizer(比如CountDownLatch)。今天我们就来讨论下同步容器。

    一.为什么会出现同步容器?

    在Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map。

    List、Set、Queue接口分别继承了Collection接口,Map本身是一个接口。

    注意Collection和Map是一个顶层接口,而List、Set、Queue则继承了Collection接口,分别代表数组、集合和队列这三大类容器。

    像ArrayList、LinkedList都是实现了List接口,HashSet实现了Set接口,而Deque(双向队列,允许在队首、队尾进行入队和出队操作)继承了Queue接口,PriorityQueue实现了Queue接口。另外LinkedList(实际上是双向链表)实现了了Deque接口。

    像ArrayList、LinkedList、HashMap这些容器都是非线程安全的。

    如果有多个线程并发地访问这些容器时,就会出现问题。

    因此,在编写程序时,必须要求程序员手动地在任何访问到这些容器的地方进行同步处理,这样导致在使用这些容器的时候非常地不方便。

    所以,Java提供了同步容器供用户使用。

    二.Java中的同步容器类

    在Java中,同步容器主要包括2类:

    1)Vector、Stack、HashTable、ConcurrentHashMap

    2)Collections类中提供的静态工厂方法创建的类

    Vector实现了List接口,Vector实际上就是一个数组,和ArrayList类似,但是Vector中的方法都是synchronized方法,即进行了同步措施。

    Stack也是一个同步容器,它的方法也用synchronized进行了同步,它实际上是继承于Vector类。

    HashTable实现了Map接口,它和HashMap很相似,但是HashTable进行了同步处理,而HashMap没有。

    Hashtable和ConcurrentHashMap有什么分别呢?它们都可以用于多线程的环境,但是当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。因为ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅需要锁定map的某个部分,而其它的线程不需要等到迭代完成才能访问map。简而言之,在迭代的过程中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。

    Collections类是一个工具提供类,注意,它和Collection不同,Collection是一个顶层的接口。在Collections类中提供了大量的方法,比如对集合或者容器进行排序、查找等操作。最重要的是,在它里面提供了几个静态工厂方法来创建同步容器类,如下图所示:

    c0bfcd2c720e0f30e9e0e64e7191aac5.png

    三.同步容器的缺陷

    从同步容器的具体实现源码可知,同步容器中的方法采用了synchronized进行了同步,那么很显然,这必然会影响到执行性能,另外,同步容器就一定是真正地完全线程安全吗?不一定,这个在下面会讲到。

    我们首先来看一下传统的非同步容器和同步容器的性能差异,我们以ArrayList和Vector为例:

    1.性能问题

    我们先通过一个例子看一下Vector和ArrayList在插入数据时性能上的差异:

    public class Test {

    public static void main(String[] args) throws InterruptedException {

    ArrayList list = new ArrayList();

    Vector vector = new Vector();

    long start = System.currentTimeMillis();

    for(int i=0;i<100000;i++)

    list.add(i);

    long end = System.currentTimeMillis();

    System.out.println("ArrayList进行100000次插入操作耗时:"+(end-start)+"ms");

    start = System.currentTimeMillis();

    for(int i=0;i<100000;i++)

    vector.add(i);

    end = System.currentTimeMillis();

    System.out.println("Vector进行100000次插入操作耗时:"+(end-start)+"ms");

    }

    }

    这段代码在我机器上跑出来的结果是:

    a69fa7cda25db21342b9958e853796f4.png

    进行同样多的插入操作,Vector的耗时是ArrayList的两倍。

    这只是其中的一方面性能问题上的反映。

    另外,由于Vector中的add方法和get方法都进行了同步,因此,在有多个线程进行访问时,如果多个线程都只是进行读取操作,那么每个时刻就只能有一个线程进行读取,其他线程便只能等待,这些线程必须竞争同一把锁。

    因此为了解决同步容器的性能问题,在Java 1.5中提供了并发容器,位于java.util.concurrent目录下,并发容器的相关知识将在下一篇文章中讲述。

    2.同步容器真的是安全的吗?

    也有有人认为Vector中的方法都进行了同步处理,那么一定就是线程安全的,事实上这可不一定。看下面这段代码:

    public class Test {

    static Vector vector = new Vector();

    public static void main(String[] args) throws InterruptedException {

    while(true) {

    for(int i=0;i<10;i++)

    vector.add(i);

    Thread thread1 = new Thread(){

    public void run() {

    for(int i=0;i

    vector.remove(i);

    };

    };

    Thread thread2 = new Thread(){

    public void run() {

    for(int i=0;i

    vector.get(i);

    };

    };

    thread1.start();

    thread2.start();

    while(Thread.activeCount()>10)   {

    }

    }

    }

    }

    在我机器上运行的结果:

    3e9bd49b45f1b241453c52af560399dd.png

    正如大家所看到的,这段代码报错了:数组下标越界。

    也许有朋友会问:Vector是线程安全的,为什么还会报这个错?很简单,对于Vector,虽然能保证每一个时刻只能有一个线程访问它,但是不排除这种可能:

    当某个线程在某个时刻执行这句时:

    for(int i=0;i

    vector.get(i);

    假若此时vector的size方法返回的是10,i的值为9,然后另外一个线程执行了这句:

    for(int i=0;i

    vector.remove(i);

    将下标为9的元素删除了。

    那么通过get方法访问下标为9的元素肯定就会出问题了。

    因此为了保证线程安全,必须在方法调用端做额外的同步措施,如下面所示:

    public class Test {

    static Vector vector = new Vector();

    public static void main(String[] args) throws InterruptedException {

    while(true) {

    for(int i=0;i<10;i++)

    vector.add(i);

    Thread thread1 = new Thread(){

    public void run() {

    synchronized (Test.class) {   //进行额外的同步

    for(int i=0;i

    vector.remove(i);

    }

    };

    };

    Thread thread2 = new Thread(){

    public void run() {

    synchronized (Test.class) {

    for(int i=0;i

    vector.get(i);

    }

    };

    };

    thread1.start();

    thread2.start();

    while(Thread.activeCount()>10)   {

    }

    }

    }

    }

    3. ConcurrentModificationException异常

    在对Vector等容器并发地进行迭代修改时,会报ConcurrentModificationException异常,关于这个异常将会在后续文章中讲述。

    但是在并发容器中不会出现这个问题。

    最后贴一个ArrayList转Vector的代码

    资料:

    《深入理解Java虚拟机》

    《Java并发编程实战》

    http://thinkgeek.diandian.com/post/2012-03-24/17905694

    http://blog.csdn.net/cutesource/article/details/5780740

    展开全文
  • /** * 解决ArrayList的三种方法 */ //1. 线程安全 add 方法使用... list = new Vector<>(); //2. Collections 工具类转换成线程安全 //List<String> list = Collections.synchronizedList(new Ar
    /**
    	   * 解决ArrayList的三种方法
    	   */
    	        //1. 线程安全 add 方法使用的是 synchronized 修饰,但其效率并不高
    	        //List<String> list = new Vector<>();
    	        //2. Collections 工具类转换成线程安全
    	        //List<String> list = Collections.synchronizedList(new ArrayList<>());
    	        //3. 复制在写入  , 内部源码使用新锁 Lock(推荐使用)
    	        List<String> list = new CopyOnWriteArrayList<>();
    
    	        for (int i = 0;i<20;i++){
    	            new Thread(()->{
    	                list.add(UUID.randomUUID().toString().substring(0,5));
    	                System.out.println(list);
    	            }).start();
    	        }
    
    展开全文
  • 并发的安全问题概述

    2021-08-09 15:39:06
    并发的安全问题概述 什么时候数据在多线程并发的环境下会存在安全问题呢? 三个条件: 条件1:多线程并发。 条件2:有共享数据。 条件3:共享数据有修改的行为。 满足以上3个条件之后,就会存在线程安全问题。 ...
  • 使用Vector()数组来解决这个问题2. 使用Connections集合3. 使用 CopyOnWriteArrayList ArrayList在多并发下的不安全问题以及解决方法 为啥不安全 多线程并发插入元素和读取元素的时候会出现 ...
  • java集合的并发问题

    2021-03-02 23:29:51
    文章目录一、Java集合中的快速失败机制解决并发修改问题的方法二、java并发编程volatile互斥锁sychronized公平锁/非公平锁可重入锁独享锁/共享锁乐观锁/悲观锁偏向锁/轻量级锁/重量级锁自旋锁锁消除synchronized和...
  • 1.容器的概述: ConcurrentMap集合类使用与底层原理分析 CopyOnWrite集合类使用与底层原理分析 并发与阻塞队列Queue讲解 ...2.同步类容器的问题 ConcurrentModificationException并发
  • 以前,我总是以为Vector在长度未知的情况下可以很好地用于非描述对象。 据我所知,我也认为它也是线程安全的不再使用Vector会发生什么变化,替代方案是什么?很好奇Vector尚未被弃用。 我想既然没有一对一的替代方法...
  • 1.使用Vector代替ArrayList:Vector是线程安全的 List<String> list=new Vector<>(); 2.使用Collections.synchronizedList()将ArrayList转换为线程安全的 List<String> list=Collections....
  • [Java教程]【实战Java高并发程序设计6】挑战无锁算法:无锁的Vector实现0 2016-02-29 18:00:06【实战Java高并发程序设计 1】Java中的指针:Unsafe类【实战Java高并发程序设计 2】无锁的对象引用:AtomicReference...
  • 并发中的集合类的主要问题就是线程安全问题,我们可以通过JDK中集合类的发展来观察集合类都有哪些问题以及如何解决。 第一代线程安全集合类 Vector、HashTable 是线程安全的:使用synchronized修饰方法。 缺点:...
  • java的并发机制及并发机制下数据安全问题的解决方案 说在前面:线程和进程 在提及多线程的时候,必须引入线程这个概念,而线程往往是和进程联系在一起的。线程和进程的关系,举一个例子,一家公司是一个进程,网景...
  • 一、概述我们都知道,在Java的Collections包含了List和Set,而List里面有ArrayList、LinkedList、还有Vector,对于很多Java初学者来说,前面两个比较常用,ArrayList查询效率比较高(底层是数组实现),而LinkedList的...
  • 4.共享模型之管程 本章内容 ·共享问题 synchronized ·线程安全分析 Monitor wait/notify ·线程状态转换 ·活跃性 Lock 解决并发的两种思路,共享、非共享
  • vector一般情况下同时读写读没问题,但当vector预留内存空间不足,需要扩容导致的变量搬移时,读存在问题,同时写也存在问题,因此需要加锁,防止并发执行。 3、map读写情况: map底层结构时红黑树,每插入一个节点...
  • Java深入学习31:ArrayList并发异常以及解决方案先看一个ArrayList多线程的下的案例。该案例会出现一些异常的情况,,期中有两个异常需要留意public classArrayListConcurrentTest {public static voidmain(String[] ...
  • 比如 tbb::concurrent_setis a class template that represents an unordered sequence of unique elements. It supports concurrent insertion, lookup and traversal, but does not support concurrent erasure. ...
  • JUC包下的容器类分为两部分,一部分是并发集合类,一部分是并发队列类,其中并发集合类可以解决我们集合使用过程中的多线程并发问题,而并发队列类则主要被当做阻塞队列使用,是线程池中的关键参数之一。接下来我们...
  • 上一篇构建的数据库连接池,今天拿来在项目中测试时,发现在处理高并发问题上有很明显的缺点。现在回过头来看我们上一篇的代码:public class ConnectionPool {/*线程安全数组*/private volatile Vector pool;...
  • Java中vector的使用方法

    2021-02-26 14:12:19
    不过,vector的大小可以根据需要增大或缩小,以适应创建vector后进行添加或移除项的操作,因此不需要考虑元素是否越界或者会不会浪费内存的问题。由vector的iterator和listIterator方法所返回的迭代器是快速失败的:...
  • 我们已经比较完整得介绍了有关无锁的概念和使用方法。相对于有锁的方法,使用无锁的方式编程更加...这里,我想向大家介绍一种使用无锁方式实现的Vector。通过这个案例,我们可以更加深刻地认识无锁的算法,同时也可...
  • 集合并发不安全问题

    2021-03-16 20:46:40
    文章目录解决集合并发不安全问题1. List并发不安全2. Set并发不安全3. Map并发不安全 解决集合并发不安全问题 1. List并发不安全 1、在并发环境下往list集合中添加或修改数据会出现ConcurrentModificationException...
  • 我们已经比较完整得介绍了有关无锁的概念和使用方法。相对于有锁的方法,使用无锁的方式编程更加...这里,我想向大家介绍一种使用无锁方式实现的Vector。通过这个案例,我们可以更加深刻地认识无锁的算法,同时也可...
  • Java并发集合

    2021-02-27 16:49:06
    Java并发集合并发集合实现1JDK1.5的出现,对于集合并发编程来说,java developer有了更多的选择。不过,在JDK1.5之前,Java也还是提供了一些解决方案。(1)最为简单直接的就是在程序中我们自己对共享变量进行加锁。...
  • 书接上文,上次聊了聊 在多线程中使用 ArrayList 会发生什么,这次我们说说平时常用的列表:Vector、ArrayList、CopyOnWriteArrayList、SynchronizedList。 Vector Vector是在 JDK 1.0 提供的,虽然没有被标记...
  • Vector的forEach()方法用于对Vector的Iterable的每个元素执行给定操作,直到该方法处理完所有元素或发生异常为止。如果该方法指定了顺序,则按照迭代顺序执行操作。操作抛出的异常将传递给调用方。直到并且除非覆盖...
  • Java并发编程之-list集合的并发.我们都知道Java集合类中的arrayList是线程不安全的。那么怎么证明是线程不安全的呢?怎么解决在并发环境下使用安全的list集合类呢?本篇是《凯哥(凯哥并发编程学习》系列之《并发集合...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 54,362
精华内容 21,744
关键字:

vector并发问题