java.util.ConcurrentModificationException异常分析
生活随笔
收集整理的這篇文章主要介紹了
java.util.ConcurrentModificationException异常分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
異常日志
2016-07-20 15:02:41,278 (New I/O worker #197) [ERROR - org.apache.flume.source.AvroSource.appendBatch(AvroSource.java:388)] Avro source r1: Unable to process event batch. Exception follows. java.util.ConcurrentModificationExceptionat java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)at java.util.ArrayList$Itr.next(ArrayList.java:851)at org.apache.flume.channel.ChannelProcessor.processEventBatch(ChannelProcessor.java:157)at org.apache.flume.source.AvroSource.appendBatch(AvroSource.java:386)at sun.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:497)at org.apache.avro.ipc.specific.SpecificResponder.respond(SpecificResponder.java:91)at org.apache.avro.ipc.Responder.respond(Responder.java:151)at org.apache.avro.ipc.NettyServer$NettyServerAvroHandler.messageReceived(NettyServer.java:188)at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)at org.apache.avro.ipc.NettyServer$NettyServerAvroHandler.handleUpstream(NettyServer.java:173)at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:558)at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:786)at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:458)at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:439)at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:311)at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:558)at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:553)at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:84)at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:471)at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:332)at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:102)at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)異常原因
首先我們可以看到異常是由ArrayList的checkForComodification拋出的。這個方法在遍歷List調用next()方法的時候會被調用,用于檢查List是否已經被修改了。
也就是說問題出在遍歷的時候,List被修改了。
進一步檢查代碼,發現List<Channel> requiredChannels = new ArrayList<Channel>();作為成員變量被定義,而在運行的過程中,這個變量會被修改。
解決辦法
- 將共享變量改為線程私有變量。這次遇到的情況,剛好是不需要定義為成員變量的情況,所以直接將成員變量改為方法局部變量,問題解決。根據實際情況來定,如果能用這種方案,當然是優先選擇這種方案。
- 使用線程安全的類替換。由于ArrayList是一個非線程安全的類,可以采用線程安全的類進行替換,如CopyOnWriteArrayList。不能使用Vector,Vector在遍歷的時候不是線程安全的。
- 使用加鎖等同步方案。
總結
以上是生活随笔為你收集整理的java.util.ConcurrentModificationException异常分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flume性能测试报告
- 下一篇: Flume学习笔记(一)安装与简单使用