1
1

More than 1 year has passed since last update.

ArrayListを更新中に参照する

Posted at

forでlistを読み込み中に、別スレッドでlist addすると
exceptionが発生する

class ReadTask implements Runnable {
    List<String> l;
    ReadTask(List l) {
        this.l = l;
    }
    @Override
    public void run() {
        try {
        for (String str:this.l) {
            System.out.println(str);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
class WriteTask implements Runnable {
    List<String> l;
    WriteTask(List l) {
        this.l = l;
    }
    @Override
    public void run() {
        for (int i=10; i<20; i++) {
            l.add(String.valueOf(i));
            System.out.println("added: " + i);
           try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}
public class Outer {
    public static void main(String[] args) {
        List<String> l = new ArrayList();
        l.add("1");
        l.add("2");
        l.add("3");
        ExecutorService es = Executors.newFixedThreadPool(3);
        es.submit(new WriteTask(l));
        es.submit(new ReadTask(l));
        es.shutdown();
    }
}
1
added: 10
2
added: 11
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 com.mycompany.mavenproject1.ReadTask.run(Outer.java:21)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
added: 12
added: 13
added: 14
added: 15
added: 16
added: 17
added: 18
added: 19

CopyOnWriteArrayListに差し替えると、listのコピーを参照しに行く
結果exceptionが発生しない
コピーをとるタイミングはjvm次第?

List<String> l = new CopyOnWriteArrayList<>();
1
added: 10
2
added: 11
3
added: 12
10
added: 13
added: 14
added: 15
added: 16
added: 17
added: 18
added: 19
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1