【问题标题】:Exception in thread "main" java.util.ConcurrentModificationException while multithreading [duplicate]多线程时线程“主”java.util.ConcurrentModificationException中的异常[重复]
【发布时间】:2020-11-23 00:35:12
【问题描述】:

我正在开发一个多线程程序,目的是通过三个线程同时将 150000 个学生添加到一个列表中,这意味着每个人将添加 50000 个。这是以下程序:

public class ThreadsStudents implements Runnable {
    
    public static List<Student> students = new ArrayList<>();
    
    @Override
    public void run() {
        for(int i = 0; i < 50000; i++) {
            students.add(Generator.generetorStudent());
        }
    }
    
    public static void threadsL(int nbThreads) {
        ArrayList<Thread> th = new ArrayList<>();
        for(int i = 0; i < nbThreads; i++) {
            th.add(new Thread(new ThreadsStudents()));
        }
        for(Thread threads: th) {
            threads.start();
        }
    }
}

我要做的是从Main类调用方法threadsL,将学生列表添加到数据库中,然后计算15次执行的平均执行时间。

public class Main {
    public static void main(String[] argv) {
        
        long startDate,endDate;
        double measure;
        double average = 0;

        ManipulationBDD basedd = new ManipulationBDD();

        for (int i = 0; i < 15; i++) {
            startDate = System.nanoTime();
            ThreadsStudents.threadsL(3);
            
            for(Student e : ThreadsStudents.students) {
                basedd.insertTable(e);
            }
            endDate = System.nanoTime();
            measure = (double) (endDate - startDate) / 1000000000;
            average = average + measure;
            basedd.empty();
        }
        average = average / 15;
        System.out.println("The average is : " + average);
    }
}

Main.java 类中,我得到以下异常:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997)
    at Main.main(Main.java:27)

第 27 行是:

for(Student e : ThreadsStudents.students) {
    basedd.insertTable(e);
}

你能帮我解决这个问题吗?

提前感谢您的帮助!

【问题讨论】:

标签: java multithreading parallel-processing synchronization java-threads


【解决方案1】:

您的程序几乎没有问题。

  1. 您的程序在 ThreadStudents 的所有线程完成之前返回主线程。所以你试图在所有线程都写完之前阅读,这就是你得到 concurrentModification 异常的原因

  2. students 是一个 ArrayList 对象,这意味着它不是线程安全的。

    public class Main {
        public static void main(String[] argv) {
    
            for (int i = 0; i < 1; i++) {
                ThreadStudents.threadsL(3);
                System.out.println(ThreadStudents.students.size());
            }
        }
    }
    
    
    
    public class ThreadStudents implements Runnable {
    
        public static List<Integer> students = new CopyOnWriteArrayList<>(); 
        // Thread safe version of array list
    
        @Override
        public void run() {
            System.out.println("Starting: " + Thread.currentThread().getName());
            for(int i = 0; i < 50000; i++) {
                students.add(1);
            }
            System.out.println("Ending " + Thread.currentThread().getName());
        }
    
        public static void threadsL(int nbThreads) {
            ExecutorService executor = Executors.newFixedThreadPool(nbThreads); 
             // creates fixed number of threads
            for(int i = 0; i < nbThreads; i++) {
                executor.execute(new ThreadStudents()); 
               // executor services will call run() from each thread
            }
            executor.shutdown(); // tell the service that no new threads can be submitted
    
            while(true) {
                try {
                    if (executor.awaitTermination(5, TimeUnit.MINUTES)) break;
                    // it will wait till all the threads have finished or Max 5 mins 
                    // before going back to main thread
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
        }
    }
    

我的输出完全符合预期,即 150,000

Starting: pool-1-thread-3
Starting: pool-1-thread-1
Starting: pool-1-thread-2
Ending pool-1-thread-3
Ending pool-1-thread-1
Ending pool-1-thread-2
150000

【讨论】:

    猜你喜欢
    • 2013-05-06
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    相关资源
    最近更新 更多