1700445541
1700445542
运气好的话,该异常马上就会报出。也许有人会说这是一个典型错误,只须把ArrayList替换成Vector即可解决问题,真的是这样吗?我们把ArrayList替换成Vector后,结果照旧,仍然抛出相同的异常,Vector已经是线程安全的,为什么还报这个错误呢?
1700445543
1700445544
这是因为他混淆了线程安全和同步修改异常,基本上所有的集合类都有一个叫做快速失败(Fail-Fast)的校验机制,当一个集合在被多个线程修改并访问时,就可能会出现ConcurrentModificationException异常,这是为了确保集合方法一致而设置的保护措施,它的实现原理就是我们经常提到的modCount修改计数器:如果在读列表时,modCount发生变化(也就是有其他线程修改)则会抛出ConcurrentModificationException异常。这与线程同步是两码事,线程同步是为了保护集合中的数据不被脏读、脏写而设置的,我们来看线程安全到底用在什么地方,代码如下:
1700445545
1700445546
public static void main(String[]args){
1700445547
1700445548
//火车票列表
1700445549
1700445550
final List<String>tickets=new ArrayList<String>();
1700445551
1700445552
//初始化票据池
1700445553
1700445554
for(int i=0;i<100000;i++){
1700445555
1700445556
tickets.add(“火车票”+i);
1700445557
1700445558
}
1700445559
1700445560
//10个窗口售票
1700445561
1700445562
for(int i=0;i<10;i++){
1700445563
1700445564
new Thread(){
1700445565
1700445566
public void run(){
1700445567
1700445568
while(true){
1700445569
1700445570
System.out.println(Thread.currentThread().getId()
1700445571
1700445572
+”—”+tickets.remove(0));
1700445573
1700445574
}
1700445575
1700445576
};
1700445577
1700445578
}.start();
1700445579
1700445580
}
1700445581
1700445582
}
1700445583
1700445584
还是火车站售票程序,有10个窗口在卖火车票,程序打印出窗口号(也就是线程号)和车票编号,很快我们就会看到这样的输出:
1700445585
1700445586
13—火车票96531
1700445587
1700445588
10—火车票96531
1700445589
1700445590
9—火车票96530
[
上一页 ]
[ :1.700445541e+09 ]
[
下一页 ]