- 浏览: 904038 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (466)
- iPhone, iOS , Objective-c (155)
- 数据库 (20)
- 设计模式 (5)
- 第三方包管理,cocoapod (2)
- 版本管理, SVN, Subversion, Git (1)
- Google, Android, Java (14)
- Wordpress (1)
- 职业素养 (3)
- 版本管理,git (3)
- 前端小技巧 (2)
- flash (1)
- javascript (5)
- Ruby (0)
- 编程语言 (1)
- 网络常识 (1)
- 找到生活好感觉 (5)
- 产品经理 (1)
- markdown (1)
- 云服务器 (1)
- iPhone (116)
- iOS (116)
- Objective-c (116)
- 学习技巧 (2)
- Google (5)
- Android (6)
- Java (21)
- python (1)
- sqlite (3)
- node.js (2)
- mongodb (2)
- 学习技巧,阅读 (2)
- 软件测试 (3)
- 架构设计 (2)
- 设计 (1)
- Spring framework (3)
- junit (1)
- Linux (2)
- 软件 (1)
- Struts2 (1)
- 版本管理 (3)
- SVN (3)
- Subversion (3)
- Git (3)
- mysql (5)
- quartz (1)
- 无关技术 (1)
- 前端 (1)
- Redis (1)
- 产品管理 (0)
- 计算机常识 (1)
- 计算机科学 (0)
- swift (1)
- 服务器 (2)
- 搜索 (1)
- Scala (1)
- J2EE (1)
- maven (1)
- 前端css (1)
- 英语 (1)
- 消息队列 (1)
- kafka (0)
- apache kafka (4)
- netbeans (1)
- IDE (2)
- 歌词 (1)
- 过滤器实现 (1)
- linux vim vi (1)
- jmeter (1)
- springcloud (1)
最新评论
-
hujingnemo:
不知道为什么打不开
CHM如何改编字体大小 -
weiboyuan:
求答案 weiboyuanios@163.com
iOS软件工程师面试题(高级) -
xueji5368:
这个现在已经广泛使用了嘛!
RoboGuice入门 -
Yao__Shun__Yu:
...
CHM如何改编字体大小 -
353144886:
非常之详细 美女求认识
sqlite数据类型 datetime处理
1.不要在foreach循环里进行元素的remove/add操作,remove元素请使用iterator方式,如并发操作,需要对iterator对象加锁.
反倒:
这个反例,在并发执行的时候是不安全的.
正确的做法是
原因是Java自带的一种迭代器快速失败机制.
迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证,快速失败迭代器会尽最大努力抛出 ConcurrentModificationException,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测 bug。
它是Java集合的一种错误检测机制。当多个线程对集合进行结构上的改变的操作时,有可能会产生fail-fast机制。记住是有可能,而不是一定。
ConcurrentModificationException不会始终指出对象已经由不同线程并发修改,如果单线程违反了规则,同样也有可能会抛出该异常。
迭代器在调用next()、remove()方法时都是调用checkForComodification()方法,该方法主要就是检测modCount == expectedModCount ? 若不等则抛出ConcurrentModificationException 异常,从而产生fail-fast机制。
方案一:在遍历过程中所有涉及到改变modCount值得地方全部加上synchronized或者直接使用Collections.synchronizedList,这样就可以解决。但是不推荐,因为增删造成的同步锁可能会阻塞遍历操作。
方案二:使用CopyOnWriteArrayList来替换ArrayList。
CopyOnWriteArrayList所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的。
该类产生的开销比较大,但是在两种情况下,它非常适合使用。1:在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时。2:当遍历操作的数量大大超过可变操作的数量时。
CopyOnWriterArrayList根本就不会产生ConcurrentModificationException异常,也就是它使用迭代器完全不会产生fail-fast机制。
反倒:
List<String> strs = new ArrayList<String>(); strs.add("1"); strs.add("2"); for (String str : strs) { if("1".equals(str)){ strs.remove(str); } }
这个反例,在并发执行的时候是不安全的.
正确的做法是
Iterator<String> it = strs.iterator(); while(it.hasNext()){ String temp = it.next(); if(删除元素的条件){ it.remove()); } }
原因是Java自带的一种迭代器快速失败机制.
迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证,快速失败迭代器会尽最大努力抛出 ConcurrentModificationException,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测 bug。
它是Java集合的一种错误检测机制。当多个线程对集合进行结构上的改变的操作时,有可能会产生fail-fast机制。记住是有可能,而不是一定。
ConcurrentModificationException不会始终指出对象已经由不同线程并发修改,如果单线程违反了规则,同样也有可能会抛出该异常。
迭代器在调用next()、remove()方法时都是调用checkForComodification()方法,该方法主要就是检测modCount == expectedModCount ? 若不等则抛出ConcurrentModificationException 异常,从而产生fail-fast机制。
方案一:在遍历过程中所有涉及到改变modCount值得地方全部加上synchronized或者直接使用Collections.synchronizedList,这样就可以解决。但是不推荐,因为增删造成的同步锁可能会阻塞遍历操作。
方案二:使用CopyOnWriteArrayList来替换ArrayList。
CopyOnWriteArrayList所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的。
该类产生的开销比较大,但是在两种情况下,它非常适合使用。1:在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时。2:当遍历操作的数量大大超过可变操作的数量时。
CopyOnWriterArrayList根本就不会产生ConcurrentModificationException异常,也就是它使用迭代器完全不会产生fail-fast机制。
public boolean add(E paramE) { ReentrantLock localReentrantLock = this.lock; localReentrantLock.lock(); try { Object[] arrayOfObject1 = getArray(); int i = arrayOfObject1.length; Object[] arrayOfObject2 = Arrays.copyOf(arrayOfObject1, i + 1); arrayOfObject2[i] = paramE; setArray(arrayOfObject2); int j = 1; return j; } finally { localReentrantLock.unlock(); } } final void setArray(Object[] paramArrayOfObject) { this.array = paramArrayOfObject; }
发表评论
-
Java的getResourceAsStream
2017-08-09 14:25 438原理是与类加载器相关 类加载器原理请参考:http://www ... -
java线程池分类及应用
2017-07-20 13:40 6251. 为什么使用线程池 诸如 Web 服务器、数据库服务器、文 ... -
Integer值传递
2017-06-15 18:24 418Java本身都是值传递式的调用,对于对象传递的是地址值。给地址 ... -
Map遍历k,v
2017-06-14 12:01 338发现还Map接口中还有一个Entry<K,V>的接 ... -
使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历
2017-02-08 11:04 911说明:keySet其实是遍历了2次,一次是转为Iterator ... -
Java原始类型转换
2016-08-15 16:25 476要获取获取对象示例 Int Integer i=myInt. ... -
Map转字符串最高效方法
2016-08-09 16:29 2571想做的事情是将一个Map类转成具体和字符串用&隔开,但 ... -
java昨天今天判断
2016-07-01 12:07 474Calendar toda ... -
按key排序
2016-03-04 16:50 495import java.util.Comparator; i ... -
Chrome浏览器查看HTTP header
2016-01-19 17:04 1748使用chrome浏览器自带的开发者工具查看http头的方法 1 ... -
部署多个项目到tomcat
2015-12-31 00:31 390If you want Tomcat to listen to ... -
JDBC步骤
2015-08-19 15:38 532JDBC连接数据库 •创建一个以JDBC连接数据库的程序 ... -
java与javascript排序回调的不同之处
2015-07-14 22:27 480Arrays.sort(values,new Comparat ... -
@Resource(type注入失败
2015-06-03 10:45 928不断的去找资料,换方法,最后发现是因为注入的service写了 ... -
eclipse常用快捷键
2015-06-01 17:12 593找出选中方法 使用 Ctrl + Shift + G -
java.util.ConcurrentModificationException 解决办法
2015-05-28 17:16 356在使用iterator.hasNext()操作迭代器的时候,如 ... -
macbook JAVA_HOME设置
2015-05-20 12:34 658搞了半个小时,相当蛋疼 因为在.bash_profile和pr ... -
Java企业设计模式
2014-10-23 20:20 0客户端表达层 为最终用户提供用户界面,例如Web浏览器。 ... -
eclipse 程序调试
2014-08-07 22:34 603http://www.56.com/u35/v_MTAyMj ... -
iBatis加锁
2014-07-10 17:48 871ibatis有事务处理,它有代理类SqlMapExecutor ...
相关推荐
需要注意的是,这里使用`iterator.remove()`而不是`list.remove()`来删除元素,这可以避免并发修改异常。 ### 三、使用HashSet特性去除重复元素 这种方法利用了HashSet的特性,即HashSet不允许有重复的元素。将...
- **容量与大小**: `size()`返回集合元素数量,`ensureCapacity()`预先设定容量。 4. **集合转换**: - `toArray()`:将集合转换为数组。 - `copyOf()`:Java 8引入,用于安全地创建数组副本。 5. **集合操作**...
面试中,Java 集合框架和多线程并发是常见的话题,因为它们是构建可扩展和健壮应用的基础。本题旨在考察候选人在实际并发场景下对 HashMap 和 ConcurrentHashMap 的理解和应用。 HashMap 和 ConcurrentHashMap 的...
这个方法是集合框架的一部分,它提供了高效的方式来进行元素的删除操作。本文将深入探讨`removeAll()`方法的性能效率,以及如何在实际应用中优化其使用。 首先,`removeAll()`方法的实现基于迭代器,这意味着它会...
迭代器模式是一种设计模式,它的主要作用是在不暴露容器内部结构的情况下,提供一种遍历容器内元素的方法。这种模式使得代码解耦,提高了灵活性。在Java等编程语言中,迭代器通常通过`Iterator`接口来实现,允许用户...
Iterator只能用于单向遍历,使用它的remove()方法可以从集合中移除元素。 6. **fail-fast机制**:这是集合框架中处理并发修改的一种机制。当集合在迭代过程中被修改,并且检测到这种修改时,迭代器会立即抛出...
而 Vector 集合实现了对线程同步的支持,因此在多线程并发访问的应用环境下,该集合本身能够保证自身具有线程安全性。 Set 接口 Set 接口代表一个无序并且不允许元素重复存在的集合。Set 接口的实现类有 HashSet、...
这个问题在单线程环境下不会出现,但在多线程并发场景下,如果多个线程同时修改一个集合,就可能导致`ConcurrentModificationException`。 标题中提到的“遍历并批量删除容器中元素”是引发此异常的一个典型操作。...
下面将详细介绍`List.remove()`方法的两种用法及其注意事项。 首先,`remove(int index)`方法用于根据提供的索引从列表中移除一个元素。索引是从0开始的,所以`remove(0)`会删除列表的第一个元素,`remove(1)`会...
HashMap不是线程安全的,适用于高并发环境下的非同步访问。在练习代码中,你将看到如何创建HashMap,插入键值对,以及获取和更新键值对的方法。 此外,集合框架还包括其他的接口和实现类,如TreeSet、TreeMap等,...
在多线程环境下,Java提供了`ConcurrentHashMap`、`CopyOnWriteArrayList`等并发安全的集合实现。这些类使用了高级并发策略,如分段锁或读写锁,以确保在并发环境下的正确性和性能。 8. **泛型(Generics)** ...
**注意事项** 在使用集合时,确保了解所选集合类型的特点和适用场景,以及在遍历过程中对集合进行修改可能会导致的并发修改异常(CooncurrentModificationException)。如果在遍历过程中需要修改集合,推荐使用迭代器...
迭代器用于遍历集合中的元素,提供remove()方法删除元素。泛型则增强了类型安全性,避免了运行时类型转换异常,提高了代码可读性和复用性。 此外,Collection接口提供了addAll()、removeAll()和retainAll()等方法,...
要找出在第二个List中已被删除的元素,我们可以通过将第一个List的元素移除掉在第二个List中存在的元素来实现: ```java list1.removeAll(list2); ``` `list1`现在只包含在第二个List中被删除的元素。 4. **...
**强制规定**:在 `subList` 场景中,需要注意对原始集合元素的增删操作,这些操作都可能导致子列表的遍历、增删产生 `ConcurrentModificationException` 异常。 **说明**:在使用 `subList` 方法时,对原始列表的...
上述操作方法是集合框架中的核心操作,它们提供了对集合元素进行增加、检索和删除的能力。 7. 迭代器模式: 迭代器(Iterator)是Java集合框架中用于遍历集合的工具。它提供了一个通用的遍历接口,使得可以通过不同...
在实际开发中,还需要关注线程安全问题,了解并发环境下如何正确使用并发集合,如ConcurrentHashMap和CopyOnWriteArrayList等。此外,深入学习集合框架的源码,可以进一步理解其内部实现机制,有助于编写更高效、更...
10. `iterator()`: 获取一个按照添加顺序遍历集合元素的迭代器。 11. `remove(Object o)`: 删除指定元素。 12. `removeAll(Collection<?> c)`: 移除集合中与指定集合相同的元素。 13. `retainAll(Collection<?> c)`:...
然而,同步也意味着其性能可能低于非同步的ArrayList,特别是在并发访问较少的情况下。 4. Stack:Stack是Vector的一个子类,实现了LIFO(后进先出)栈的数据结构。它的操作主要是push和pop,以及peek查看栈顶元素...
- `next()`:返回集合中的下一个元素。 - `remove()`:移除迭代器中最近返回的那个元素。 通过使用`Iterator`,可以在遍历集合的同时安全地移除元素,而不会引发并发修改异常。 #### 五、总结 理解Java集合框架的...