首页 > 编程知识 正文

java多线程处理list不重复,java多线程共享全局变量

时间:2023-05-03 14:24:05 阅读:29610 作者:3786

我们在日常编写代码中,经常使用多线程来提高效率。 在使用多线程的过程中,将数据修改到List集合是不可避免的。

试着向ArrayList中添加数据。

publicstaticvoidmain (字符串[ ] args ) { ListInteger list=new ArrayList; for(intI=10000000; i=1; I----{list.add(0); } System.out.println ('源集合数: ' list.size ) ); listintegernewlist=new ArrayList (; long start=system.current time millis (; executorserviceexecutor=executors.newfixedthreadpool (100; for(integerinteger3360list ) { executor.submit ()-{ new list.add } integer1); ); } executor.shutdown (; try { executor.await termination (6,TimeUnit.MINUTES ); } catch (互联互通) { e.printStackTrace ); } longend=system.current time millis (; System.out.println (时间: ) (结束-开始) ms ); System.out.println (新收藏数: ) newlist.size ); 使用123456789101121314151617181920212232425线程池向ArrayList中添加1000万个元素。 让我们来看看结果:

为什么新list’的数据会少于1千万呢?

因为ArrayList不是线程安全的,所以在以高并发方式将数据添加到list时,数据可能会丢失。

此外,如果一个线程正在遍历列表,而另一个线程修改该列表,则会报告concurrentmodificationexception错误

那么,如果需要同时操作数据,收集和处理结果,该怎么办呢?

一.使用载体

从源代码介绍中可以看到,Viector是线程安全的,稍后我们会介绍,如果不要求线程安全,我们建议使用ArrayList。 因为ArrayList的单点效率更高。

从源代码中可以看到:

/* * setsthesizeofthisvector.ifthenewsizeisgreaterthanthe * currentsize, new { @ code null } itemsareaddedtotheendof * the vector.ifthenewsizeislessthanthecurrentsize, all * componentsatindex { @ code new size } andgreaterarediscarded.* * @ paramnewsizethenewsizeofthisvector * @ throwsarrayindexoutofboundsexceptionifthenewsizeisnegative */publicsynchronizedvoidsetsize (int new size ) { modCount; 新尺寸元素计数(if ) ensurecapacityhelper (新尺寸); }else{for(intI=newsize; I元素计数; I ) {元素数据[ I ]=null; } } elementCount=newSize; }/* * * returnsthecurrentcapacityofthisvector.* * @ return the current

capacity (the length of its internal * data array, kept in the field {@code elementData} * of this vector) */ public synchronized int capacity() { return elementData.length; } /** * Returns the number of components in this vector. * * @return the number of components in this vector */ public synchronized int size() { return elementCount; } /** * Tests if this vector has no components. * * @return {@code true} if and only if this vector has * no components, that is, its size is zero; * {@code false} otherwise. */ public synchronized boolean isEmpty() { return elementCount == 0; } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051

Vector里面的操作方法,都加上了synchronized 关键字。下面来使用Vector走一遍代码:

public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for (int i = 10000000; i >= 1; i--) { list.add(0); } System.out.println("源集合数量:"+list.size()); List<Integer> newVector = new Vector<>(); long start = System.currentTimeMillis(); ExecutorService executor = Executors.newFixedThreadPool(100); for (Integer integer : list) { executor.submit(()->{ newVector.add(integer+1); }); } executor.shutdown(); try { executor.awaitTermination(6, TimeUnit.MINUTES); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("时间:"+(end-start)+"ms"); System.out.println("newVector数量:"+newVector.size()); } 1234567891011121314151617181920212223242526

看下结果:


我们可以发现现在,新Vector里面的数量正好是一千万个。但是时间上要长于ArrayList。

二、使用Collections.synchronizedList()进行包装

public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for (int i = 10000000; i >= 1; i--) { list.add(0); } System.out.println("源集合数量:"+list.size()); /** * Collections.synchronizedList()包装 */ List<Integer> newCollList = Collections.synchronizedList(new ArrayList<>()); long start = System.currentTimeMillis(); ExecutorService executor = Executors.newFixedThreadPool(100); for (Integer integer : list) { executor.submit(()->{ newCollList.add(integer+1); }); } executor.shutdown(); try { executor.awaitTermination(6, TimeUnit.MINUTES); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("时间:"+(end-start)+"ms"); System.out.println("newCollList新集合数量:"+newCollList.size()); } 1234567891011121314151617181920212223242526272829

结果:


我们可以发现也是一千万条。时间上和Vector差距不大,因给给ArrayList进行了包装以后等于是给ArrayList里面所有的方法都加上了 synchronized,和Vector实现效果差不多。

总结:在并发给List进行修改时,可以使用Vector或者Collections.synchronizedList(),不要直接使用ArrayList,在非并发情况下尽量使用ArrayList;

版权声明:本文为flycp原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:使用多线程往List添加数据_cpown的博客-CSDN博客_多线程向list添加元素

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。