`

循环打印java.util.ConcurrentModificationException

阅读更多

 java.util.ConcurrentModificationException

的原因:

 

的原因:

 

 

报错位置是

         at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)

         at java.util.HashMap$KeyIterator.next(HashMap.java:828)

         at org.hibernate.jdbc.AbstractBatcher.closeStatements(AbstractBatcher.java:314)

         at org.hibernate.jdbc.ConnectionManager.cleanup(ConnectionManager.java:382)

         at org.hibernate.jdbc.ConnectionManager.close(ConnectionManager.java:324)

         at org.hibernate.impl.SessionImpl.close(SessionImpl.java:298)

         at org.hibernate.ejb.EntityManagerImpl.close(EntityManagerImpl.java:86)

 

 

查回源码(hibernate3.2.4 sp1

 

        

 

	/**
	 * Actually releases the batcher, allowing it to cleanup internally held
	 * resources.
	 */
	public void closeStatements() {
		try {
			releasing = true;

			try {
				if (batchUpdate!=null) batchUpdate.close();
			}
			catch (SQLException sqle) {
				//no big deal
				log.warn("Could not close a JDBC prepared statement", sqle);
			}
			batchUpdate=null;
			batchUpdateSQL=null;

			Iterator iter = resultSetsToClose.iterator();
			while ( iter.hasNext() ) {
				try {
					logCloseResults();
					( (ResultSet) iter.next() ).close();
				}
				catch (SQLException e) {
					// no big deal
					log.warn("Could not close a JDBC result set", e);
				}
				catch (Throwable e) {
					// sybase driver (jConnect) throwing NPE here in certain cases
					log.warn("Could not close a JDBC result set", e);
				}
			}
			resultSetsToClose.clear();

			iter = statementsToClose.iterator();
			while ( iter.hasNext() ) {
				try {
					closeQueryStatement( (PreparedStatement) iter.next() );
				}
				catch (SQLException e) {
					// no big deal
					log.warn("Could not close a JDBC statement", e);
				}
			}
			statementsToClose.clear();
		}
		finally {
			releasing = false;
		}
	}

 

 

 

 

 

 

 

 

查回源码(hibernate3.2.7 ga

 

 

	/**
	 * Actually releases the batcher, allowing it to cleanup internally held
	 * resources.
	 */
	public void closeStatements() {
		try {
			releasing = true;

			try {
				if ( batchUpdate != null ) {
					batchUpdate.close();
				}
			}
			catch ( SQLException sqle ) {
				//no big deal
				log.warn( "Could not close a JDBC prepared statement", sqle );
			}
			batchUpdate = null;
			batchUpdateSQL = null;

			Iterator iter = resultSetsToClose.iterator();
			while ( iter.hasNext() ) {
				try {
					logCloseResults();
					( ( ResultSet ) iter.next() ).close();
				}
				catch ( SQLException e ) {
					// no big deal
					log.warn( "Could not close a JDBC result set", e );
				}
				catch ( ConcurrentModificationException e ) {
					// this has been shown to happen occasionally in rare cases
					// when using a transaction manager + transaction-timeout
					// where the timeout calls back through Hibernate's
					// registered transaction synchronization on a separate
					// "reaping" thread.  In cases where that reaping thread
					// executes through this block at the same time the main
					// application thread does we can get into situations where
					// these CMEs occur.  And though it is not "allowed" per-se,
					// the end result without handling it specifically is infinite
					// looping.  So here, we simply break the loop
					log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
					break;
				}
				catch ( Throwable e ) {
					// sybase driver (jConnect) throwing NPE here in certain
					// cases, but we'll just handle the general "unexpected" case
					log.warn( "Could not close a JDBC result set", e );
				}
			}
			resultSetsToClose.clear();

			iter = statementsToClose.iterator();
			while ( iter.hasNext() ) {
				try {
					closeQueryStatement( ( PreparedStatement ) iter.next() );
				}
				catch ( ConcurrentModificationException e ) {
					// see explanation above...
					log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
					break;
				}
				catch ( SQLException e ) {
					// no big deal
					log.warn( "Could not close a JDBC statement", e );
				}
			}
			statementsToClose.clear();
		}
		finally {
			releasing = false;
		}
	}

 

 

 

 

两个版本中的closeStatements方法不同,3.2.7中加了对ConcurrentModificationException的处理,当遇到这个异常时,就break,这样就不会再循环打印这个错误了。

 

查了一下jboss下的hibernate3.jar,这个包使用的是3.2.4版本的,如果修改这个错误,升级一下hibernate的版本即可。

另一个问题,商用上有两台内容服务器,部署的包一样,而环境也是一样(没认真检查),两台机都有打包电子书的操作,为什么一台机会循环打印日志,而另一台则不会呢?

认真看看hibernate3.2.7中加了对ConcurrentModificationException处理的注释:

大概意思是:这只会在很小概率下发生的,当用上事务管理和事务超时时,事务超时会通过hibernate已注册事务同步的一个单独线程进行回调,这时候这个单独的线程通过这段时间再执行任务,而同时应用的主线程也在执行,这样我们就会陷入一种像日冕物质抛射的状况,尽管这个本身就是不允许的,如果我们不采取措施处理这个问题,最终结果就是一个无止境的循环。。。

 

 

这里提及到事务超时,这里想起了内容1和内容2两台服务器,一台的日志暴涨,一台却不会,后台查一下是jboss的事务超时时间不同,内容1的是好几个小时,而内容2的是5分钟,应该跟这个有关系了。

 

 

解决方法:更换hibernate的版本和修改jboss的事务超时时间。

分享到:
评论

相关推荐

    JAVA.BUG模式详解

    使用`synchronized`关键字、`volatile`变量、`java.util.concurrent`包中的工具类等可以有效地管理并发。 四、内存泄漏 Java中的内存泄漏并不像C++那样直接导致资源耗尽,但过度持有对象引用会导致垃圾收集器无法...

    迭代大师的修炼之道:Java中Iterator与增强for循环的深度解析

    import java.util.ArrayList; import java.util.Iterator; public class IteratorExample { public static void main(String[] args) { ArrayList<String> names = new ArrayList(); names.add("Ada Lovelace");...

    13.foreach循环_java_

    在Java编程语言中,`foreach`循环,也称为增强型for循环或迭代器循环,是处理数组和集合数据的一种简洁高效的方式。这个小视频详细介绍了如何在Java中正确使用`foreach`循环,让我们深入探讨一下相关知识点。 首先...

    java_util_concurrent_user_guide并发工具包详解

    Java并发工具包(java.util.concurrent)是Java编程中不可或缺的一部分,它为多线程环境提供了高效、安全且易用的工具。这个包包含了各种类和接口,帮助开发者编写高效的并发程序,避免了直接操作线程所带来的复杂性...

    java 迭代及迭代器的小例子

    例如,在java.util.concurrent包中的ConcurrentLinkedQueue等线程安全的集合类,它们的迭代器是弱一致性(weakly consistent)的,这意味着迭代器不会抛出ConcurrentModificationException,但可能不反映对集合的...

    详解Java 集合类 List 的那些坑

    在直接遍历 List 集合元素时增加、删除元素会报错,例如使用 for 循环遍历 List 时删除元素,会抛出 ConcurrentModificationException 异常。解决方法是使用 Iterator 迭代器遍历 List,并使用 Iterator 的 remove ...

    Java程序员容易犯的10个错误

    正确做法是使用迭代器,但使用增强for循环(for-each)配合`list.remove()`会抛出`ConcurrentModificationException`。正确的迭代器移除方式如下: ```java Iterator<String> iter = list.iterator(); while ...

    遍历并批量删除容器中元素出现ConcurrentModificationException原因及处置

    - 使用`synchronized`关键字或者`java.util.concurrent`包中的并发工具类(如`Semaphore`、`CyclicBarrier`、`ReentrantLock`等)来控制并发访问和修改集合。 - 考虑使用Java 8的流(Stream)API,它们提供了一种...

    阿里巴巴Java代码规范PDF.zip

    - 使用`synchronized`关键字或`java.util.concurrent`包中的工具类处理多线程同步问题。 - 避免在循环中调用`synchronized`方法,可能导致性能下降。 8. **效率优化**: - 避免在循环体内部进行不必要的计算,如...

    java哈希表(1).zip

    在Java中,`HashMap`类就是对哈希表的一种实现,它是`java.util`包的一部分。`HashMap`提供了线程非同步的快速存储和检索,其内部使用了数组和链表(或红黑树)来存储数据。 1. **哈希函数**:哈希函数是哈希表的...

    java实现遍历Map的方法

    首先,Java提供了两种主要的方式来遍历Map:迭代器(Iterator)方式和增强for循环(foreach)方式。 ### 1. 迭代器方式 迭代器方式是通过调用Map的`keySet()`方法获取所有的键,然后通过迭代器遍历这些键,再使用`...

    Java开发规约.rar

    - 避免过度使用`synchronized`,考虑使用`java.util.concurrent`包中的并发工具类。 6. **集合操作** - 尽量使用`foreach`循环遍历集合,避免索引操作。 - 避免使用`Collection.remove()`操作,因其可能抛出`...

    内置迭代器的linked list例题

    然后,我们通过调用`iterator()`方法获取迭代器,并使用while循环配合`hasNext()`和`next()`方法遍历并打印出链表中的所有元素。 值得注意的是,迭代器提供了`remove()`方法,允许在遍历过程中安全地删除元素。如果...

    java对于Json文件的解析范例

    - 遍历方式:推荐使用迭代器`Iterator`遍历ArrayList,而不是`for-each`循环,因为`for-each`在删除元素时可能导致ConcurrentModificationException。 以上内容涵盖了Java解析JSON的基本方法、时间戳转换、文件...

    java-collection-all-in-one.pdf

    在java.util包和java.util.concurrent包中,Java集合框架被细分为两大类:基础集合类和并发集合类。基础集合类主要用于单线程环境中,而并发集合类则专为多线程环境设计,提供了线程安全的集合操作。 Java集合框架...

    Concurrent.zip

    在IT行业中,尤其是在Java开发领域,`java.util.concurrent`(JUC)包是并发编程的核心工具包,它提供了丰富的类和接口,使得开发者能够高效、安全地处理多线程环境中的任务。`Concurrent.zip`文件很可能是包含了...

    Java多线程基础-02、数组定义方式一、访问、注意事项.rar

    使用增强for循环(foreach)可以简化代码,但要确保在遍历过程中没有其他线程修改数组,否则可能会抛出`ConcurrentModificationException`。如果存在并发修改,可以使用`Collections.synchronizedList`或`...

    Java程序员们最常犯的10个错误.docx

    然而,这返回的是一个内部类`java.util.Arrays.ArrayList`,它不支持添加元素。如果需要可变的`ArrayList`,应该使用构造函数来创建新的`ArrayList`,如: ```java ArrayList<String> arrayList = new ArrayList...

    Java实验五线程.pdf

    同时,`java.util.concurrent`包提供了更高级的线程管理工具,如`ExecutorService`、`Future`、`Semaphore`等,用于更复杂和高效的并发编程。 总之,这个实验旨在帮助学习者理解Java中线程的概念,以及如何创建、...

    常见数据结构的Java实现

    1. `List`接口:`List`是`java.util`包下的一个接口,它继承自`Collection`接口,并添加了对有序元素序列的支持。`List`接口规定了添加、删除和访问元素的方法,如`add()`, `remove()`, 和 `get()`。 2. `...

Global site tag (gtag.js) - Google Analytics