Java线程和并发修改例外

Pau*_*ell 1 java concurrency multithreading exception

我知道这是一个愚蠢的问题,但无法解决如何解决这个问题,我以前没有太多使用线程的经验.

下面应该首先创建一个定时器,它将每10秒执行一次命令output.write(mylist),它将简单地输出mylist的内容.

其次,它循环通过我拥有的大约3个列表,并且每个列表创建一个线程,它将继续循环获取列表中的下一个单词.请注意:这是精简版,并没有完整,所以请不要评论arraylist /列表,而是错误本身.

有一个并发修改异常经常发生,但并不是所有的时候它都尝试输出.write
我猜这是因为其他线程之一当前正在保存一些东西到mylist?我该如何解决这个问题?

非常感谢!

    Runnable timer = new Runnable() {
        public void run() {
            try {
                while (true) {
                    Thread.sleep(10000);
                    output.write(mylist);
                }
            } catch (InterruptedException iex) {}
        }
    };
    Thread timerThread = new Thread(timer);
    timerThread.start();

    for (final ValueList item : list) {

        Runnable r = new Runnable() {
            public void run() {
                try {
                    while (true) {

                        char curr = item.getNext();

                         mylist.addWord(curr);
                    }
                } catch (InterruptedException iex) {}
            }
        };

        Thread thr = new Thread(r);
        thr.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

Gra*_*ray 9

有一个并发修改异常经常发生,但并不是所有的时候它都试图output.write...

问题是(我假设)该output.write(...)方法myList在另一个线程正在调用的同时迭代您myList.addWord(curr);.除非myList是并发集合,否则不允许这样做.

我该如何解决这个问题?

myList每次访问它时都需要进行同步- 在这种情况下,当您输出它或向其添加单词时.

  synchronized (myList) {
      output.write(mylist);
  }
  ...

  synchronized (myList) {
      myList.addWord(curr);
 }
Run Code Online (Sandbox Code Playgroud)

您还可以output.write(mylist)将其定义为同步列表,在这种情况下,Collections.synchronizedList(...)包装器类将为您处理同步.

  synchronized (myList) {
      output.write(mylist);
  }
  ...

  synchronized (myList) {
      myList.addWord(curr);
 }
Run Code Online (Sandbox Code Playgroud)

如果这是一个被称为吨次的高性能方法,那么你也可以使用a ConcurrentLinkedQueue但这显然是一个队列而不是列表.