是什么导致使用Collections.synchronizedList的java.util.concurrentmodificationexception?

我有以下代码给出了java.util.concurrentmodificationexception.

我不是处理线程的专家,但是我认为如果我有一个同步列表,那么它应该是线程安全的…

编辑:
这是我方法的完整代码.

@Override
    protected List< ExportSchedule > export( List< ExportSchedule > exportSchedules )
    {
        final HandleSystemDoiAdministrator handleSystemDoiAdministrator = HandleSystemDoiAdministratorFactory.getInstance();
        final List< ExportSchedule > successfullyExported = new ArrayList<>();
        final List<ExportError> unsuccessfullyExported = Collections.synchronizedList( new ArrayList<ExportError>() );

        ExecutorService executorService = Executors.newFixedThreadPool( 10 );

        for ( final ExportSchedule exportSchedule : exportSchedules )
        {
            executorService.execute( new Runnable() {
                public void run()
                {
                    String doi = exportSchedule.getDoi().getDoi();
                    String url = exportSchedule.getDoi().getUrl();

                    boolean success = handleSystemDoiAdministrator.updateDoiHandle( doi, url );

                    if ( success )
                    {
                        successfullyExported.add( exportSchedule );
                    }
                    else
                    {
                        if ( handleSystemDoiAdministrator.isWarn() )
                        {
                            DoiErrorHelper.persistExportError(
                                ExportInterface.HANDLE_SERVER,
                                doi,
                                "Warning: Error exporting DOI " + doi + " with URL " + url + " to Handle Server: "
                                        + handleSystemDoiAdministrator.getResponseOutcome().toString(),
                                exportSchedule.getDoi().getDoiPool() );
                        }
                        if ( handleSystemDoiAdministrator.isFatal() )
                        {


                            synchronized(unsuccessfullyExported) {
                            unsuccessfullyExported.add( DoiErrorHelper.createExportError( doi, "Fatal: Error exporting DOI " + doi + " with URL " + url + " to Handle Server: "
                                        + handleSystemDoiAdministrator.getResponseOutcome().toString(), null, new Date(), exportSchedule.getDoi().getDoiPool().getName(),
                                        exportSchedule.getDoi().getDoiPool().getDoiPrefix(), ExportInterface.HANDLE_SERVER ) );}
                        }
                    }
                }
            } );
        }

        executorService.shutdown();
        try
        {
            executorService.awaitTermination( 1, TimeUnit.MINUTES );
        }
        catch ( InterruptedException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return successfullyExported;
    }

编辑2:

这是错误:

    [exec]
     [exec] [#|2014-05-08T10:16:12.951+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=203;_ThreadName=Thread-2;|    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:894)|
#]
     [exec]
     [exec] [#|2014-05-08T10:16:12.951+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=203;_ThreadName=Thread-2;|    at java.util.HashMap$EntryIterator.next(HashMap.java:934)|#]
     [exec]
     [exec] [#|2014-05-08T10:16:12.951+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=203;_ThreadName=Thread-2;|    at java.util.HashMap$EntryIterator.next(HashMap.java:932)|#]
     [exec]
     [exec] [#|2014-05-08T10:16:12.952+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=203;_ThreadName=Thread-2;|    at java.util.AbstractMap.toString(AbstractMap.java:518)|#]
     [exec]
     [exec] [#|2014-05-08T10:16:12.952+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=203;_ThreadName=Thread-2;|    at ch.ethz.id.wai.doi.export.handle.DoiExport2HSProcessing$1.r
un(DoiExport2HSProcessing.java:106)|#]
     [exec]
     [exec] [#|2014-05-08T10:16:12.952+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=203;_ThreadName=Thread-2;|    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoo
lExecutor.java:1145)|#]
     [exec]
     [exec] [#|2014-05-08T10:16:12.952+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=203;_ThreadName=Thread-2;|    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPo
olExecutor.java:615)|#]
     [exec]
     [exec] [#|2014-05-08T10:16:12.953+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=203;_ThreadName=Thread-2;|    at java.lang.Thread.run(Thread.java:722)|#]
     [exec]
     [exec] [#|2014-05-08T10:16:28.552+0200|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=157;_ThreadName=Thread-2;|0|#]
     [exec]
     [exec] [#|2014-05-08T10:16:31.221+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=222;_ThreadName=Thread-2;|Exception in thread "pool-41-thread-10" |#]
     [exec]
     [exec] [#|2014-05-08T10:16:31.223+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=222;_ThreadName=Thread-2;|java.util.ConcurrentModificationException
     [exec]     at java.util.HashMap$HashIterator.nextEntry(HashMap.java:894)
     [exec]     at java.util.HashMap$EntryIterator.next(HashMap.java:934)
     [exec]     at java.util.HashMap$EntryIterator.next(HashMap.java:932)
     [exec]     at java.util.AbstractMap.toString(AbstractMap.java:518)
     [exec]     at ch.ethz.id.wai.doi.export.handle.DoiExport2HSProcessing$1.run(DoiExport2HSProcessing.java:106)
     [exec]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
     [exec]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
     [exec]     at java.lang.Thread.run(Thread.java:722)
     [exec] |#]

DoiExport2HSProcessing.java是包含方法的类,第106行是将错误添加到列表的位置.

解决方法:

ConcurrentModificationException与同步或线程安全直接无关.多线程将使此异常的条件(参见下文)不可见,但也可能在一个线程中发生!

同步列表可防止您以未定义状态从多个线程访问列表.但是您仍然可以在修改列表时迭代元素.这将导致ConcurrentModificationException.

您不得在迭代过程中使用add(),remove()等修改列表.唯一有效的修改是使用Iterator(remove())或ListIterator(add()和set())的方法!

上一篇:java-在不同的类(和不同的包)中同步两个方法


下一篇:Gradle项目同步在Android Studio 2.3.3中失败