Java集合中的线程安全问题

介绍

JDK中提供了很多集合实现,本文不会介绍有哪些集合的接口以及实现类,而是介绍如何在多线程情况下使用这些集合。

阅读更多…

如果您还不太了解Java的整个集合体系的话,请查看《Java开发成长之路第一年》。如果您还想要了解线程的相关内容,请查看《Java多线程》。
线程不安全

java.util.HashMap、java.util.ArrayList、java.util.LinkedList、java.util.HashSet等集合实现类都是线程不安全的,在多线程环境下使用的话,将会得到无法预期的结果。
遍历不安全

java.util.Hashtable、java.util.Vector等集合类在多线程环境下,如果只是调用put、get、remove等方法的话是能保证线程安全的,但如果进行遍历的话就无法保证线程安全了。这种情况也叫做“条件线程安全”。
线程安全

java.util.concurrent.ConcurrentHashMap、java.util.concurrent.CopyOnWriteArrayList、java.util.concurrent.ConcurrentArraySet等是线程安全的。
Map

下面是验证HashMap问题的示例代码:
[codesyntax lang="java"]
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * java.util.HashMap的线程不安全测试,这里会有如下两种情况: * <ul> * <li>输出的Map元素个数不对</li> * <li>死循环(线程数多了更容易出现)</li> * </ul> * @author suren * @date 2017年2月22日 下午3:31:09 /public class HashMapTest{ static Map<String, String> map; public static void main(String[] args) { map = new HashMap<String, String>(); long begin = System.currentTimeMillis(); ThreadGroup group = new ThreadGroup("HashMap thread test from surenpi.com"); List<Thread> threadList = new ArrayList<Thread>(); int threadCount = 10; for(int i = 0; i < threadCount; i++) { Thread thread = new Thread(group, new Runnable() { @Override public void run() { for(int j = 0; j < 200 ; j++) { map.put(Thread.currentThread().getName() + j, ""); map.get(Thread.currentThread().getName() + j); } } }); threadList.add(thread); } for(Thread thread : threadList) { thread.start(); } while(group.activeCount() > 0) {} System.out.println(map.size()); System.out.println("take time : " + (System.currentTimeMillis() - begin)); }}
[/codesyntax]
以下是线程安全的Map实现类的效率比较示例:
[codesyntax lang="java"]
import java.util.ArrayList;import java.util.Hashtable;import java.util.List;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/
* * Hashtable和ConcurrentHashMap效率比较 * @author suren * @date 2017年2月22日 下午4:27:56 /public class ThreadSafeMapTest{ /* * @param args */ public static void main(String[] args) { mapTest(new Hashtable<String, String>()); mapTest(new ConcurrentHashMap<String, String>()); } static void mapTest(final Map<String, String> map) { long begin = System.currentTimeMillis(); ThreadGroup group = new ThreadGroup("HashMap thread test from surenpi.com"); List<Thread> threadList = new ArrayList<Thread>(); int threadCount = 10; for(int i = 0; i < threadCount; i++) { Thread thread = new Thread(group, new Runnable() { @Override public void run() { for(int j = 0; j < 9999 ; j++) { map.put(Thread.currentThread().getName() + j, ""); map.get(Thread.currentThread().getName() + j); } } }); threadList.add(thread); } for(Thread thread : threadList) { thread.start(); } while(group.activeCount() > 0) {} System.out.println(map.getClass() + " take time : " + (System.currentTimeMillis() - begin)); }}
[/codesyntax]
List

下面是ArrayList和LinkedList线程不安全的示例代码:
[codesyntax lang="java"]
import java.util.ArrayList;import java.util.LinkedList;import java.util.List;/** * java.util.LinkedList和java.util.ArrayList的线程不安全测试,这里会有如下两种情况: * <ul> * <li>ArrayList可能会出现下标越界的异常</li> * <li>LinkedList的元素个数不正确</li> * </ul> * @author suren * @date 2017年2月22日 下午3:31:09 */public class NonThreadSafeListTest{ public static void main(String[] args) { listTest(new LinkedList<String>()); listTest(new ArrayList<String>()); } static void listTest(final List<String> list) { long begin = System.currentTimeMillis(); ThreadGroup group = new ThreadGroup("HashMap thread test from surenpi.com"); List<Thread> threadList = new ArrayList<Thread>(); int threadCount = 10; for(int i = 0; i < threadCount; i++) { Thread thread = new Thread(group, new Runnable() { @Override public void run() { for(int j = 0; j < 200 ; j++) { list.add(Thread.currentThread().getName() + j); } } }); threadList.add(thread); } for(Thread thread : threadList) { thread.start(); } while(group.activeCount() > 0) {} System.out.println(list.size()); System.out.println(list.getClass() + " take time : " + (System.currentTimeMillis() - begin)); }}
[/codesyntax]

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 一. Java基础部分.................................................
    wy_sure阅读 9,291评论 0 11
  • 不足的地方请大家多多指正,如有其它没有想到的常问面试题请大家多多评论,一起成长,感谢!~ String可以被继承吗...
    启示录是真的阅读 8,084评论 3 3
  • 转载自:Java集合框架实例 1- 介绍 集合是程序和语言的基本思想。应用程序通常都会应用到集合,例如雇员的信息,...
    01_小小鱼_01阅读 3,184评论 0 1
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 5,078评论 0 2
  • 小编费力收集:给你想要的面试集合 1.C++或Java中的异常处理机制的简单原理和应用。 当JAVA程序违反了JA...
    八爷君阅读 10,221评论 1 114

友情链接更多精彩内容