第一种 - Iterator(迭代器)
Iterator<String> iterator = list.iterator();
while(iter.hasNext())
{
iter.next();
}
这种方式在循环执行过程中会进行数据锁定,性能稍差。
同时,如果你想在进行遍历的过程中,移除List中的某个元素,只能调用iterator.remove方法,而不能使用list.remove()方法,否则会抛出并发修改异常(java.util.ConcurrentModificationException)。
第二种 - foreach
for(String tmp:list)
{
//do something
}
foreach只是Java提供的语法糖,内部调用Iterator(第一种),换汤不换药,因此比 Iterator 稍慢。
第三种 - get(i)
int listSize = list.size();
for (int i = 0; i < listSize; i++) {
list.get(i);
}
内部不锁定,效率最高,但是当写多线程时要考虑并发操作的问题。
Iterator(迭代器)的使用 - Fail fast问题
前面我们提到了,如果你想在使用Iterator(迭代器)进行遍历的过程中,移除List中的某个元素,只能调用iterator.remove方法,而不能调用list.remove()方法,否则一定会抛出并发修改异常(java.util.ConcurrentModificationException)。
注意,当这个异常被抛出时,并不意味着这个list一定正在被多个线程同时使用,而在同一个线程中既一边遍历 list,一边调用list.remove()方法,也会抛出ConcurrentModificationException。
解决办法
可以使用CopyOnWriteArrayList来替换ArrayList。
CopyOnWriteArrayList为何物?
CopyOnWriteArrayList是ArrayList 的一个线程安全的变体,其中所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的。
因此,该类产生的开销比较大,但是在两种情况下,它非常适合使用:
- 在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时。
- 当遍历操作的数量大大超过可变操作的数量时。
遇到这两种情况使用CopyOnWriteArrayList来替代ArrayList再适合不过了。
那么,为什么CopyOnWriterArrayList可以替代ArrayList呢?
- CopyOnWriterArrayList的无论是从数据结构、定义都和ArrayList一样。它和ArrayList一样,同样是实现List接口,底层使用数组实现。在方法上也包含add、remove、clear、iterator等方法。
- CopyOnWriterArrayList根本就不会产生ConcurrentModificationException异常,也就是它使用迭代器完全不会产生fail-fast机制。
Reference
- Java提高篇(三四)—–fail-fast机制 - https://www.cnblogs.com/chenssy/p/3870107.html
FEATURED TAGS
algorithm
algorithmproblem
architecturalpattern
architecture
aws
c#
cachesystem
codis
compile
concurrentcontrol
database
dataformat
datastructure
debug
design
designpattern
distributedsystem
django
docker
domain
engineering
freebsd
git
golang
grafana
hackintosh
hadoop
hardware
hexo
http
hugo
ios
iot
java
javaee
javascript
kafka
kubernetes
linux
linuxcommand
linuxio
lock
macos
markdown
microservices
mysql
nas
network
networkprogramming
nginx
node.js
npm
oop
openwrt
operatingsystem
padavan
performance
programming
prometheus
protobuf
python
redis
router
security
shell
software testing
spring
sql
systemdesign
truenas
ubuntu
vmware
vpn
windows
wmware
wordpress
xml
zookeeper