美文网首页多线程专家
Java集合中的线程安全问题

Java集合中的线程安全问题

作者: LinuxSuRen | 来源:发表于2017-06-19 09:07 被阅读149次

介绍

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]

相关文章

  • Java集合中的线程安全问题

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

  • 集合类与Java锁浅析

    集合类不安全问题 List ArrayList不是线程安全类,在多线程同时写的情况下,会抛出java.util.C...

  • 「Java面试必会」谈谈并发包java .util.concur

    说到集合,就知道有的集合类并不是线程安全的,那Java中怎么保证集合是线程安全的? java .util.conc...

  • volatile关键字

    线程安全问题 Java多线程带来的一个问题是数据安全问题,判断一段Java代码是否有线程安全问题可从以下几点入手:...

  • 简单聊聊 Java线程的并发

    哈喽大家好,上一篇文章我们聊了聊Java线程的基础知识,这一篇文章我们就来聊聊线程中的线程安全问题 线程安全问题 ...

  • 线程安全问题

    线程安全问题 本篇主要讲解 线程安全问题,演示什么情况下会出现线程安全问题,以及介绍了 Java内存模型 、vol...

  • java 线程安全问题的解决办法 和死锁

    线程安全问题的解决办法 线程 安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题的。 java线程同步...

  • java多线程(壹)——线程与锁

    线程与线程安全问题 所有的线程安全问题都可以概况为三个点:原子性,可见性、有序性——————by Java多线程编...

  • 关于Java中的 CopyOnWriteArraySet

    最近做的课程设计中用到了Java线程安全的集合类,因此关于对Java线程安全集合类的理解做个简单记录。Java集合...

  • 第2章 并发编程的其他基础知识

    目录 并行与并发区别 Java中的线程安全问题 Java中共享变量的内存可见性问题 synchronized关键字...

网友评论

    本文标题:Java集合中的线程安全问题

    本文链接:https://www.haomeiwen.com/subject/ypqgqxtx.html