`
yidongkaifa
  • 浏览: 4063045 次
文章分类
社区版块
存档分类
最新评论

Java5 多线程(九)--jdk1.5同步集合

 
阅读更多

在JDK1.5之前没有推出同步集合的时候,可以通过Conllections集合工具类的synchronized+集合名称如:synchronizedSet(Set),现在不需要这种方式了使用ConcurrentHashMap,ConcurrentSkipListMap,ConcurrentSkipListSet,ConcurrentLinkedQueue等这些集合即可.
1>线程不安全的集合出现的问题,死循环.
Race Condition(也叫做资源竞争),是多线程编程中比较头疼的问题特别是Java多线程当中,
经常会因为多线程同时访问相同的共享数据,而造成数据的不一致性,为了解决这个问题
通常来说需要加上同步标识synchronized,来保证数据串行的访问,但是synchronized是个性能杀手,
过多的使用会导致性能下降,特别是扩展性下降,使得系统不能使用多个CPU资源,这是性能测试当中
经常遇到的问题.
然而有一个公司的ERP系统出现了问题,然后就叫Java的高级工程师来解决,该工程师通发现当500个并发用访问的时候,居然把所有的CPU都压得满满的,通过过DTrace for Java工具发现很多CPU都在做同一件事,
那就是不停的执行一条语句(HashMap.get()方法).这是为什么呢?
我们知道遍历Map集合的时候,是这样的情形(下面只是伪代码):
while(hasNext()){
//每当循环一次cursor加1
//假设该集合里面有4个元素(count=4),如果循环到最后一次了cursor=4,就在此时另一个线程
//跑来把集合里面的一个元素给删除了(remove()),这时候count=3了,这时候上一个线程接着执行
//它会去判断hasNext(),但是count!=cursor了,而本来是相等的.这样就是死循环了.
}
hasNext(){
if(cursor==count){
return false;//不需要再循环了
}
return true;
}
总结: 线程不安全的集合,如果多个线程同时对其进行添加和删除操作, 有可能会出现致命的错误.

2>HashSet和HashMap关系
通过查看HashSet源码:
publicHashSet() {
map=newHashMap<E,Object>();
}发现HashSet实际上就是通过HashMap来实现的,不过它只用到了HashMap的key
3>线程不安全集合还有另一个隐患
public static void main(String[] args) {
//Collection users = new CopyOnWriteArrayList();
Collection users = new ArrayList();
users.add(new User("张三",28));
users.add(new User("李四",25));
users.add(new User("王五",31));
Iterator itrUsers = users.iterator();
while(itrUsers.hasNext()){
System.out.println("aaaa");
User user = (User)itrUsers.next();
if("张三".equals(user.getName())){
users.remove(user);
} else {
System.out.println(user);
}
}
}
运行程序发现出现异常:


这是为什么?
跟进AbstractList 343行:



分析如下:
我们来看一下这个
while(itrUsers.hasNext()){
User user = (User)itrUsers.next();
if("张三".equals(user.getName())){
users.remove(user);
} else {
System.out.println(user);
}
}
查看hasNext源码:

如果把 if("张三".equals(user.getName()))改成 if("王五".equals(user.getName()))
输出结果如下:

出现了第一次出现的异常,分析如下:
当第一循环执行到next()时候expectedModCount=3 modCount=3 cursor=1,size()=3
当第二循环执行到next()时候expectedModCount=3 modCount=3 cursor=2,size()=3
当第三循环执行到next()时候expectedModCount=3 modCount=4 cursor=3,size()=2
发现cursor任然不等于size(),循环人仍在继续,最后发现expectedModCount!=modCount抛出异常.所以控制太输出这样的结果.
要想迭代的时候同时操作集合可以使用JDK1.5提供的线程安全的集合,
只需要把集合改成如下即可:Collection users = new CopyOnWriteArrayList();


转载请注明出处 : http://blog.csdn.net/johnny901114/article/details/8696032




分享到:
评论

相关推荐

    java8集合源码-java:JDK8新特性

    java8集合源码定时器和定时器任务 定时器是线程调度任务以在后台线程中执行的工具。 任务可以安排为一次性执行,或定期重复执行。 与每个 Timer 对象相对应的是一个单独的后台线程,用于按顺序执行所有计时器的任务...

    concurrent 多线程 教材

    30 Java5 多线程实践.mht 31 Java 理论与实践 并发集合类.mht 32 Java 理论与实践 构建一个更好的 HashMap.mht 33 Java 理论与实践 JDK 5_0 中更灵活、更具可伸缩性的锁定机制.mht 34 Java 理论与实践 流行的...

    java8集合源码分析-JUC:高并发与多线程

    高并发与多线程 Stargazers over time 线程 线程的创建和启动 线程的sleep、yield、join 线程的状态 代码在 部分。 synchronized关键字(悲观锁) synchronized(Object) 不能用String常量、Integer、Long。 锁住的是...

    JAVA2核心技术(中文的PDF).part3.rar

    全面覆盖Java 2技术的高级主题,包括:多线程、集合框架、网络API、数据库编程、分布式对象等,深入探究了Swing、Java 2D API、JavaBean、Java安全模式、XML、注释、元数据等主题,同时涉及本地方法、国际化以及JDK ...

    java jdk实列宝典 光盘源代码

    一个支持多线程的服务器框架,GeneralServer.java; 代理服务器,ProxyServer.java; telnet客户端,访问系统的telnet服务实质上是与telnet服务建立socket连接,默认的telnet服务的端口是23,TelnetClient.java; ...

    涵盖了90%以上的面试题

    jdk1.5新特性 jdk1.7新特性 jdk1.8新特性 java语言有哪些优点? 同一个.java文件中是否可以有多个main方法 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 如何在main方法执行前输出”hello ...

    Java开发技术大全(500个源代码).

    ThreadImRunnable.java 继承Runnable接口实现多线程 mulThread.java 创建多个线程对象的类 demoJoin.java 演示使用join()以确保主线程最后结束 clicker.java 一个计数用的线程类 demoPri.java 调用上面这个类...

    JavaSourceCodeAnalysis:JDK二进制阅读笔记,包括Java常用集合类和Java常用和发工具(同步工具,线程安全集合,线程池)两个部分-java source code analysis

    其保障线程安全的手段是使用同步的包装所有函数,和其他线程安全的集合比起来,在多线程环境中效率很低。 ArrayDeque是基于循环拆分的双向数组,可扩容,拆分栈和样式。 平均情况下,作为栈比Stack效率更高,作为...

    Java高级工程师简历模板18k+

    2.熟练使用常用的java集合类以及常用集合的源码,熟悉多线程以及同步容器以及并发容器的使用,AQS,CAS,lock,volatilte,synchronized等; 3.对Java虚拟机、JMM、垃圾收集机制、GC算法、JVM常用配置参数、GC参数、...

    Java2核心技术.part5

    1.2.10多线程 1.2.11动态性 1. 3 Java与Internet 1. 4 Java发展简史 1.5关于Java的常见误解 第2章Java程序设计环境 2.1安装Java开发工具箱 2.1.1下载JDK 2.1.2设置执行路径 2.1.3安装库源代码...

    java基础案例与开发详解案例源码全

    12.1.5 为什么需要多线程309 12.1.6 线程分类309 12.2 线程的生命周期309 12.2.1 线程的状态及转换310 12.2.2 线程睡眠311 12.2.3 线程让步313 12.2.4 线程的加入313 12.3 线程的调度和优先级314 12.4 线程的同步315...

    Java面试宝典-经典

    50、多线程有几种实现方法?同步有几种实现方法? 33 51、启动一个线程是用run()还是start()? . 33 52、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 33 53、线程的基本概念...

    张孝祥Java就业培训教程.pdf

    5.2 多线程的同步 5.3 线程间的通信 5.4 线程生命的控制 第6章 Java API 6.1 理解API的概念 6.2 工具软件的介绍与使用 6.3 String类和StringBuffer类 6.4 基本数据类型的对象包装类 6.5 集合类 6.6 Hashtable与...

    AIC的Java课程1-6章

     理解和应用Java异常,常用类,IO,集合和多线程等开发技术。  课时安排  总学时:52学时  授课:48学时 (含约20学时实验)  考试:4学时  预备知识  了解和使用操作系统,...

    [Java参考文档].JDK_API 1.6

    java.util.concurrent.atomic 类的小工具包,支持在单个变量上解除锁的线程安全编程。 java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。 java.util.jar 提供读写 JAR ...

    疯狂JAVA讲义

    第1章 Java概述 1 1.1 Java语言的发展简史 2 1.2 Java的竞争对手及各自优势 4 1.2.1 C#简介和优势 4 1.2.2 Ruby简介和优势 4 1.2.3 Python的简介和优势 5 1.3 Java程序运行机制 5 1.3.1 高级语言的运行机制 6...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    多线程与并发 GC机制 GC收集器类型 串行 CMS 并行 G1 算法 复制 标记清理 标记整理 分区 新生代 eden survivor 老年代(old区) 永久代(perm区) 版本变化 1.5 1.6 1.7 1.8 1.9 IO/NIO IO...

Global site tag (gtag.js) - Google Analytics