fail fast

在并发的时候,如果线程A正遍历一个collection(List, Map, Set etc.),这时另外一个线程B却修改了该collectionsize,线程A就会抛出一个错:ConcurrentModificationException,表明:我正读取的内容被修改掉了,你是否需要重新遍历?或是做其它处理?这就是fail-fast的含义。

 

Fail-fast是并发中乐观(optimistic)策略的具体应用,它允许线程自由竞争,但在出现冲突的情况下假设你能应对,即你能判断出问题何在,并且给出解决办法。悲观(pessimistic)策略就正好相反,它总是预先设置足够的限制,通常是采用锁(lock),来保证程序进行过程中的无错,付出的代价是其它线程的等待开销: 

 

Doug Leaconcurrent包给出了另外一种解决方案,Copy On Write。它的CopyOnWriteArrayListCopyOnWriteArraySet会在线程B试图修改数据容器时,给出一个copy出来的容器(当然,我们程序中是感觉不到的),这样线程A在老版本的v上遍历,线程B则在新版本的v上修改,两者互不相干,也决不会出现ConcurrentModificationException。它的代价则主要是在容器的copy上,当并发程度越高,其开销也越高。

 

 

所以,Fast Fail被引入JDK的一个基本前提是:你绝大多数的情形,仅仅是在遍历一个collection,不会有另外的线程会对它做update。如此,它的效率是最充分的。但如果你不断遇到ConcurrentModificationException的异常时,则要考虑是否要进行一定次数的重新遍历,或者干脆采用悲观策略锁住资源来保证线程安全。

你可能感兴趣的:(thread)