尽管使用同步来对集合进行分类

发布于 2025-01-23 13:04:45 字数 1674 浏览 0 评论 0原文

我尝试使用螺纹方法对集合进行排序,其中方法单独调用比较器类,

public class ThreadedSort{
   public ThreadedSort(){
       ThreadedIDSort idSort=new ThreadedIDSort();
       ThreadedNameSort nameSort=new ThreadedNameSort();
       ThreadedSalarySort salarySort=new ThreadedSalarySort();

        ExecutorService threadExecutor=Executors.newCachedThreadPool();

        threadExecutor.execute(idSort);
        threadExecutor.execute(nameSort);
        threadExecutor.execute(salarySort);

   }
}

每个螺纹方法看起来都如下:

public class ThreadedIDSort implements Runnable, EmployeeInterface {
    public synchronized void run(){
        employeeList.sort(new IDComparator());
    }
  }

ID隔离器类如下:

public class IDComparator implements Comparator<Employee> {
    @Override
    public int compare(Employee a, Employee b) {
        return a.getID()-b.getID();
    }

}

雇员是具有属性名称,ID,薪金和帖子的对象的列表:

ArrayList<Employee> employeeList=new ArrayList<>();

尽管我在运行方法之前添加了同步,编辑列表仍然给出contrentModificationException,

Exception in thread "pool-2-thread-2" Exception in thread "JavaFX Application Thread" java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList.sort(ArrayList.java:1723)
    at Client.Sort.Threaded.ThreadedNameSort.run(ThreadedNameSort.java:9)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:831)

我尝试使用线程立即使用名称,帖子和ID进行排序。

I tried to sort the collection using threaded methods where the methods call comparator classes individually

public class ThreadedSort{
   public ThreadedSort(){
       ThreadedIDSort idSort=new ThreadedIDSort();
       ThreadedNameSort nameSort=new ThreadedNameSort();
       ThreadedSalarySort salarySort=new ThreadedSalarySort();

        ExecutorService threadExecutor=Executors.newCachedThreadPool();

        threadExecutor.execute(idSort);
        threadExecutor.execute(nameSort);
        threadExecutor.execute(salarySort);

   }
}

Each threaded method looks like this:

public class ThreadedIDSort implements Runnable, EmployeeInterface {
    public synchronized void run(){
        employeeList.sort(new IDComparator());
    }
  }

The ID Compartator class is as follows:

public class IDComparator implements Comparator<Employee> {
    @Override
    public int compare(Employee a, Employee b) {
        return a.getID()-b.getID();
    }

}

The employeeList is a list of objects having attributes name, id, salary and post:

ArrayList<Employee> employeeList=new ArrayList<>();

Though I added synchronized before run method, editing the list still gives ConcurrentModificationException

Exception in thread "pool-2-thread-2" Exception in thread "JavaFX Application Thread" java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList.sort(ArrayList.java:1723)
    at Client.Sort.Threaded.ThreadedNameSort.run(ThreadedNameSort.java:9)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:831)

I am trying to sort using name, post and ID all at once using threads.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凶凌 2025-01-30 13:04:45

Rob Spoor解释了为什么ConcurrentModificationException不一定与线程有关。但是,您应该知道这一点:

同步关键字在run()方法中没有效果。

当您编写同步方法时,

    public synchronized void bar() {
        ...
    }

这与您在示例中编写的情况相同

    public void bar() {
        synchronized(this) {
             ...
        }
    }

,您提交给执行程序服务的三个任务中的每个任务都是不同的运行对象。关键字<代码>此是指三个run()方法中的每个对象。在三个不同对象上同步的三个不同线程与无同步相同。

仅当线程在相同对象上同步时,同步才有意义。规则是,没有两个线程可以同时同步在相同的对象上同步。

Rob Spoor explained why ConcurrentModificationException isn't necessarily about threading. But also, you should know this:

The synchronized keyword on the run() method in your example has no effect.

When you write a synchronized method,

    public synchronized void bar() {
        ...
    }

That's the same as if you wrote,

    public void bar() {
        synchronized(this) {
             ...
        }
    }

In your example, each of the three tasks that you submit to the executor service is a different Runnable object. The keyword, this, refers to a different object in each of the three run() methods. Three different threads synchronizing on three different objects is the same as no synchronization at all.

Synchronization is only meaningful when the threads synchronize on the same object. The rule is, no two threads will ever be allowed to synchronize on the same object at the same time.

被翻牌 2025-01-30 13:04:45

confurrentModification也可以在单线螺纹应用程序中发生。当收集既修改又迭代时就会发生。这可能与以下内容一样简单:

for (String s : myStringList) {
    if ("X".equals(s)) {
        myStringList.remove(s);
    }
}

请注意,所谓的并发集合来自java.util.concurrent,已设计用于支持这一点,但大多数(全部?)来自java .util即使您应用同步也存在相同的问题。

不查看雇主的完全是IDCOMPARATOR做什么,很难说出为什么在这种特定情况下抛出例外情况。

A ConcurrentModification can also occur in single threaded applications. They occur when a collection is both modified and iterated over. That can be as simple as the following:

for (String s : myStringList) {
    if ("X".equals(s)) {
        myStringList.remove(s);
    }
}

Note that the so-called concurrent collections, from java.util.concurrent, have been designed to support this, but most (all?) from java.util have the same issue, even if you apply synchronisation.

Without seeing what employeeList is exactly, and what IDComparator does, it's difficult to say why the exception is thrown in this specific case.

煮酒 2025-01-30 13:04:45

该问题是通过同时运行不同的线程来修改相同的“雇主”。

选择之一是克隆雇员,并分配单独的排序列表。

例子:

ArrayList<Employee> employeeList=new ArrayList<>();

ArrayList<Employee>  employeeListByName = employeeList.clone();

ArrayList<Employee>  employeeListBySalary = employeeList.clone();

// use copy of list in respective thread

ThreadedIDSort  -> use employeeList
ThreadedNameSort -> use employeeListByName
ThreadedSalarySort -> use employeeListBySalary

The issue is with same 'employeeList' being modified by concurrently running different threads.

One of the options is to clone the employeeList and assign separate list for sorting.

Example:

ArrayList<Employee> employeeList=new ArrayList<>();

ArrayList<Employee>  employeeListByName = employeeList.clone();

ArrayList<Employee>  employeeListBySalary = employeeList.clone();

// use copy of list in respective thread

ThreadedIDSort  -> use employeeList
ThreadedNameSort -> use employeeListByName
ThreadedSalarySort -> use employeeListBySalary
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文