我嘗試使用執行緒方法對集合進行排序,其中方法單獨呼叫比較器類
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();
}
}
employeeList 是具有屬性 name、id、salary 和 post 的物件串列:
ArrayList<Employee> employeeList=new ArrayList<>();
雖然我在運行方法之前添加了同步,但編輯串列仍然會給出 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)
我正在嘗試使用執行緒一次使用名稱、帖子和 ID 進行排序。
uj5u.com熱心網友回復:
Rob Spoor 解釋了為什么ConcurrentModificationException不一定與執行緒有關。而且,你應該知道這一點:
您示例中方法的synchronized關鍵字run()無效。
當你寫一個同步方法時,
public synchronized void bar() {
...
}
就像你寫的一樣,
public void bar() {
synchronized(this) {
...
}
}
在您的示例中,您提交給執行器服務的三個任務中的每一個都是不同的Runnable物件。關鍵字 ,在這三種方法this的每一種中都指代不同的物件。run()三個不同的執行緒在三個不同的物件上同步與根本沒有同步是一樣的。
只有當執行緒在同一個物件上同步時,同步才有意義。規則是,不允許兩個執行緒同時在同一個物件上同步。
uj5u.com熱心網友回復:
AConcurrentModification也可以出現在單執行緒應用程式中。它們發生在集合同時被修改和迭代時。這可以像下面這樣簡單:
for (String s : myStringList) {
if ("X".equals(s)) {
myStringList.remove(s);
}
}
請注意,所謂的并發集合 fromjava.util.concurrent旨在支持這一點,但大多數(全部?) fromjava.util都有相同的問題,即使您應用同步也是如此。
如果不知道究竟employeeList是什么,又是什么IDComparator,很難說為什么在這種特定情況下會引發例外。
uj5u.com熱心網友回復:
問題在于通過同時運行不同的執行緒來修改相同的“employeeList”。
一種選擇是克隆employeeList 并分配單獨的串列進行排序。
例子:
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/467464.html
