多线程处理时线程“main”java.util.concurrentmodificationexception中出现异常

h22fl7wq  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(419)

这个问题在这里已经有答案了

并发修改异常[重复](9个答案)
上个月关门了。
我正在开发一个多线程程序,打算用三个线程同时在一个列表中添加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();
        }
    }
}

我要做的是调用这个方法 threadsLMain 类,将学生列表添加到数据库中,然后计算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);
}

你能帮我吗?
提前感谢您的帮助!

b4wnujal

b4wnujal1#

你的程序没有什么问题。
在threadstudents的所有线程完成之前,您的程序将返回到主线程。因此,您试图在所有线程都已写入之前读取,这就是为什么会出现concurrentmodification异常的原因
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();
            }
        }

    }
}

我的产量和预期完全一样,是15万

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

相关问题