您的位置 首页 > 德语词汇

fail-safe是什么意思?用法、例句(fail-safe 和 fail-fast 都是什么鬼?)

大家好,如果您还对fail-safe是什么意思?用法、例句不太了解,没有关系,今天就由本站为大家分享fail-safe是什么意思?用法、例句的知识,包括fail-safe 和 fail-fast 都是什么鬼?的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

原文链接:https://mp.weixin.qq.com/s/dPA7zohM2LfBrZT-sfQnyg

java.util包下的属于fail-fast,快速失败~

fail-safe是什么意思?用法、例句(fail-safe 和 fail-fast 都是什么鬼?)

java.util.concurrent包下的属于fail-safe,安全失败~

简单来说就是fail-fast在迭代时,如果发现该集合数据结构被改变(modCount!=expectedModCount),就会抛出ConcurrentModificationException

小伙伴们可以参考下下面的代码简单实验一下~

实验对象是Hashtable,这里采用jdk1.7的写法~

因为博主还在研究下文中ConcurrentHashMap在7和8中有啥不一样

classEimplementsRunnable{\n\nHashtable<String,String>hashtable;\n\npublicE(Hashtable<String,String>hashtable){\nthis.hashtable=hashtable;\n}\n\nprivatevoidadd(Hashtable<String,String>hashtable){\nfor(inti=0;i<10000000;i++){\nhashtable.put("a",""+i);\n}\n}\n\n@Override\npublicvoidrun(){\nadd(hashtable);\n}\n}\n\npublicclassD{\n\n\npublicstaticvoidmain(String[]args){\nHashtable<String,String>hashtable=newHashtable<String,String>();\nhashtable.put("1","2");\nhashtable.put("2","2");\nhashtable.put("3","2");\nhashtable.put("4","2");\nhashtable.put("15","2");\n\n\nnewThread(newE(hashtable)).start();\n\nSet<Map.Entry<String,String>>entries=hashtable.entrySet();\nIterator<Map.Entry<String,String>>iterator=entries.iterator();\ntry{\nThread.sleep(10);\n}catch(InterruptedExceptione){\ne.printStackTrace();\n}\nwhile(iterator.hasNext()){\nSystem.out.println(iterator.next());\niterator.remove();\n}\n}\n}\n

效果如图:

当集合数据结构发生变化时,这两个值是不相等的,所以会抛出该异常~。

虽然HashTable是线程安全的,但是它有fail-fast机制,所以在多线程情况下进行迭代也不能去修改它的数据结构!

fail-fast机制不允许并发修改!

classEimplementsRunnable{\n\nConcurrentHashMap<String,String>concurrentHashMap;\n\npublicE(ConcurrentHashMap<String,String>concurrentHashMap){\nthis.concurrentHashMap=concurrentHashMap;\n}\n\nprivatevoidadd(ConcurrentHashMap<String,String>concurrentHashMap){\nfor(inti=0;i<100000;i++){\nconcurrentHashMap.put("a"+i,""+i);\n}\n}\n\n@Override\npublicvoidrun(){\nadd(concurrentHashMap);\n}\n}\npublicclassD{\n\n\n\npublicstaticvoidmain(String[]args){\n\nConcurrentHashMap<String,String>concurrentHashMap=newConcurrentHashMap<String,String>();\n\nconcurrentHashMap.put("1","2");\nconcurrentHashMap.put("2","2");\nconcurrentHashMap.put("3","2");\nconcurrentHashMap.put("4","2");\nconcurrentHashMap.put("15","2");\n\nnewThread(newE(concurrentHashMap)).start();\ntry{\nThread.sleep(2);\n}catch(InterruptedExceptione){\ne.printStackTrace();\n}\n\nSet<Map.Entry<String,String>>entries=concurrentHashMap.entrySet();\n\n\nfor(Map.Entry<String,String>entry:entries){\nSystem.out.println(entry);\n//这里不用调用iterator去remove\nconcurrentHashMap.remove(entry.getKey());\n}\n\n}\n}\n

效果如图:

代码运行讲解,线程A往里加数据,线程B遍历它的数据,并删除。

可以看到这里并没有报错~,但是它也不能保证遍历到所有的值(可以理解为无法获取到最新的值)

有没有感受到一丝丝安全失败的感觉~

哈哈哈它的特点就是允许并发修改,不会抛出ConcurrentModificationException,但是无法保证拿到的是最新的值

不知道小伙伴们看完上面的实验代码有没有疑惑

(???(???(???*)

别急~我们先来看看使用这个迭代器中发生了什么?

创建迭代器的过程

图一可以看到会去创造一个EntryIterator,而它又继承了HashIterator,在初始化时,会先调用父类的构造器。

图三可以发现HashIterator在初始化时,会去调用advance方法(这里就不展开这个concurrentHashMap结构啦~)这里的重点在最后一张图,它调用的是UNSAFE.getObjectVolatile。

它的作用是强制从主存中获取属性值。

小伙伴们可以自行对比下HashMap或者上面的HashTable,他们都是直接拿到代码中定义的这个Entry[]~。

不知道小伙伴们get得到这个点没有~

4ye在网上搜这个fail-fast和fail-safe的区别时,看到下面这张图。

几乎都在说fail-safe会复制原来的集合,然后在复制出来的集合上进行操作,然后就说这样是不会抛出ConcurrentModificationException异常了。

可是这种说法是不严谨的~它描述的情况应该是针对这个CopyOnWriteArrayList或者CopyOnWriteArraySet的情况(下面的源码讲到~)

CopyOnWriteArrayList源码

可以发现这里snapshot的指针是始终指向这个原数组的(当你创建迭代器的时候)

当你添加数据时,它会复制原来的数组,并在复制出来的数组上进行修改,

然后再设置进去,可以发现至始至终都没有修改到这个原数组,

所以迭代器中的数据是不受影响的~

fail-safe也是得具体情况具体分析的。

嘿嘿现在回答上面那个为啥可以remove的问题啦~

重点在红框处,pred为null表示是数组的头部,此时调用setEntryAt,这里也是出现了这个UNSAFE

UNSAFE.putOrderedObject这段代码的意思就是:

有序的(有延迟的)强制更新数据到主内存。(不能立刻被其他线程发现)

这些和Java的JMM(Java内存模型)有关!

java.util包下的属于fail-fast,

不允许并发修改,如果并发修改的话会导致在迭代过程中抛出ConcurrentModificationException,

出发点是modCount!=expectedModCount。

java.util.concurrent包下的属于fail-safe,

允许并发修改,但是无法保证在迭代过程中获取到最新的值。

concurrentHashMap获取和修改数据时,是通过UNSAFE类直接从主内存中获取或者更新数据到主内存~

CopyOnWriteArrayList或者CopyOnWriteArraySet,就直接复制原来的集合,然后在复制出来的集合上进行操作

如果你还想了解更多这方面的信息,记得收藏关注本站。

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023