主题:在并发比较高的情况下出现空指针 ConcurrentModificationException: n

xiong2426 2020年12月01日 110

在环境偶发一个问题报错

java.util.ConcurrentModificationException: null at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719) ~[?:1.8.0_144] at java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:742) ~[?:1.8.0_144] at org.beetl.sql.core.db.ClassDesc.(ClassDesc.java:68) ~[beetlsql-2.12.17.RELEASE.jar:?] at org.beetl.sql.core.db.TableDesc.getClassDesc(TableDesc.java:109) ~[beetlsql-2.12.17.RELEASE.jar:?] at org.beetl.sql.core.db.AbstractDBStyle.generalInsert(AbstractDBStyle.java:379) ~[beetlsql-2.12.17.RELEASE.jar:?] at org.beetl.sql.core.db.AbstractDBStyle.genInsertTemplate(AbstractDBStyle.java:371) ~[beetlsql-2.12.17.RELEASE.jar:?] at org.beetl.sql.core.SQLManager.getScript(SQLManager.java:415) ~[beetlsql-2.12.17.RELEASE.jar:?] at org.beetl.sql.core.SQLManager.generalInsert(SQLManager.java:1162) ~[beetlsql-2.12.17.RELEASE.jar:?] at org.beetl.sql.core.SQLManager.insertTemplate(SQLManager.java:1123) ~[beetlsql-2.12.17.RELEASE.jar:?] at org.beetl.sql.core.SQLManager.insertTemplate(SQLManager.java:1088) ~[beetlsql-2.12.17.RELEASE.jar:?] at com.yszr.acct.common.tools.BaseBeetlDao.save(BaseBeetlDao.java:50) ~[module-common-6.0.0-SNAPSHOT.jar:?]

使用如下的代码示例 进行高并发模拟

/**

 * 定义一个不安全方法:在高并发情况下得不到想要的结果
 * queryTimes 是一个不安全的属性;
 * getTimes是一个不安全方法;
 */
static int queryTimes = 0;
public static int getTimes(){
    queryTimes = queryTimes +1;
    return queryTimes;
}


/**
 * 200个线程来执行获取getTimes
 * @param args
 */
public static void main(String[] args) {
    SQLManager sqlManager = getOracleSqlManager();
    parallelTesk(1000, new Runnable() {
        @Override
        public void run() {
            System.out.println(getTimes());
            sqlManager.insertTemplate(getFsTnstrdflow());
        }
    });
}


/**
 * 高并发测试:
 * 创建threadNum个线程;
 * 执行任务task
 * @param threadNum 线程数量
 * @param task 任务
 */
public static void parallelTesk(int threadNum, Runnable task){

    // 1. 定义闭锁来拦截线程
    final CountDownLatch startGate = new CountDownLatch(1);
    final CountDownLatch endGate  = new CountDownLatch(threadNum);

    // 2. 创建指定数量的线程
    for (int i = 0; i <threadNum; i++) {
        Thread t = new Thread(() -> {
            try {
                startGate.await();
                try {
                    task.run();
                } finally {
                    endGate.countDown();
                }
            } catch (InterruptedException e) {

            }
        });

        t.start();
    }

    // 3. 线程统一放行,并记录时间!
    long start =  System.nanoTime();

    startGate.countDown();
    try {
        endGate.await();
    } catch (InterruptedException e) {
    }

    long end = System.nanoTime();
    System.out.println("cost times :" +(end - start));
}

代码运行出现该报错

Exception in thread "Thread-761" java.util.ConcurrentModificationException at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719) at java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:742) at org.beetl.sql.core.db.ClassDesc.(ClassDesc.java:68) at org.beetl.sql.core.db.TableDesc.getClassDesc(TableDesc.java:109) at org.beetl.sql.core.db.AbstractDBStyle.generalInsert(AbstractDBStyle.java:379) at org.beetl.sql.core.db.AbstractDBStyle.genInsertTemplate(AbstractDBStyle.java:371) at org.beetl.sql.core.SQLManager.getScript(SQLManager.java:415) at org.beetl.sql.core.SQLManager.generalInsert(SQLManager.java:1162) at org.beetl.sql.core.SQLManager.insertTemplate(SQLManager.java:1123) at org.beetl.sql.core.SQLManager.insertTemplate(SQLManager.java:1088) at com.yszr.acct.repository.autocode.tools.SQLTool$1.run(SQLTool.java:45) at com.yszr.acct.repository.autocode.tools.SQLTool.lambda$0(SQLTool.java:70)

版本号 beetlsql-2.12.17.RELEASE

闲大赋 2020年12月01日

应该是classes定义问题,线程不安全

改成这个就好了,我需要更新一下版本,你可以明天使用最新版本看看


private Map<Class,ClassDesc> classes = new ConcurrentHashMap<>();

  • xiong2426 :好的 感谢大佬(2020年12月01日)
  • 闲大赋 :别客气,你的信息足够丰富,一眼能看出来(2020年12月01日)
  • 闲大赋 :<version>2.13.6.RELEASE</version>这是beetlsql最新版本,可能需要等回下才能在中央仓库看到(2020年12月01日)
  • xiong2426 :等会儿我试试 再测试一下,再次感谢(2020年12月01日)
  • xiong2426 :我们使用这个 gradle api 'com.ibeetl:beetl-framework-starter:1.2.20.RELEASE' 那是不是需要单独 引入beetlsql2.13.6的版本(2020年12月01日)
  • 闲大赋 :<artifactId>beetl-framework-starter</artifactId> <version>1.2.36.RELEASE</version> 用这个,不过需要等一下上仓库(2020年12月01日)
  • xiong2426 :感谢大佬 已更新 测试一下并发 没有报错了(2020年12月02日)
  • 闲大赋 :https://www.oschina.net/news/122355/beetlsql-2-13-8-release-released 最新版本(2020年12月03日)