Я пытался попробовать проблему производителя и потребителя с помощью ArrayList (я знаю, что Arraylist isnt threadsafe), и я убедился, что я поставил список с ключевым словом synchronized
, но все еще попал в ConcurrentModificationException
. Это ошибкаArrayList не является потокобезопасным даже с синхронизированным блоком?
Начиная Производитель Просьба предоставить сведения о задании: TestJob Работа завершена: TestJob Исключение в потоке "потребитель" java.util.ConcurrentModificationException в java.util.ArrayList $ Itr.checkForComodification (Unknown Source) в java.util.ArrayList $ Itr.next (Unknown Source) в test.thread.Consumer.run (Consumer.java:25) в java.lang.Thread.run (Unknown Source)
Это мой код:
package test.thread;
import java.util.List;
import java.util.Scanner;
public class Producer implements Runnable {
private List<String> jobs = null;
public Producer(List<String> jobs) {
this.jobs = jobs;
}
@Override
public void run() {
System.out.println("Starting Producer");
while(true)
{
synchronized (jobs) {
try {
if (jobs.isEmpty()) {
System.out.println("Please provide the job details: ");
Scanner scanner = new Scanner(System.in);
String job = scanner.nextLine();
jobs.add(job);
scanner.close();
jobs.notifyAll();
Thread.sleep(4000);
} else {
jobs.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
package test.thread;
import java.util.List;
public class Consumer implements Runnable {
private List<String> jobs = null;
public Consumer(List<String> list) {
this.jobs = list;
}
@Override
public void run() {
while(true)
{
synchronized (jobs) {
try {
if (jobs.isEmpty()) {
jobs.wait();
} else {
for (String job : jobs) {
System.out.println("Job completed: " + job);
jobs.remove(job);
Thread.sleep(2000);
}
jobs.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
package test.thread;
import java.util.ArrayList;
import java.util.List;
public class TestThread {
public static void main(String...strings)
{
List<String> list = new ArrayList<String>();
Producer producer = new Producer(list);
Consumer consumer = new Consumer(list);
Thread prodThread = new Thread(producer, "producer");
Thread consThread = new Thread(consumer, "consumer");
prodThread.start();
consThread.start();
}
}
* Все * обращения к ArrayList должны быть синхронизированы в одном экземпляре. Это не так в вашем коде (например, геттеры и сеттеры). –
Не могли бы вы рассказать? – Rupesh
@ AndyTurner Ах, убрал мой комментарий. –