首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >删除CopyOnWriteArrayList并发访问问题

删除CopyOnWriteArrayList并发访问问题
EN

Stack Overflow用户
提问于 2020-05-19 16:45:05
回答 1查看 282关注 0票数 0

我很难找到如何在没有线程异常的情况下删除CopyOnWriteAccess的元素。

代码语言:javascript
复制
Exception in thread "Thread-3649" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4
    at java.base/java.util.concurrent.CopyOnWriteArrayList.elementAt(CopyOnWriteArrayList.java:386)
    at java.base/java.util.concurrent.CopyOnWriteArrayList.remove(CopyOnWriteArrayList.java:479)
    at com.mycompany.playmatehunter.Downloader.init(Downloader.java:28)
    at com.mycompany.playmatehunter.Downloader.run(Downloader.java:19)
    at java.base/java.lang.Thread.run(Thread.java:834)

我有下面的下载程序

代码语言:javascript
复制
public class Downloader extends Thread{
    private CopyOnWriteArrayList<String> url_list;
    private String chemin;

    public Downloader( CopyOnWriteArrayList<String> l, String chemin)
    {
        this.url_list = l;
        this.chemin = chemin;
    }

    public void run()
    {
        init();   
    }

    public synchronized void init() // the list is already synchronized
    {
        if (!url_list.isEmpty())
        {
            int alea = (int)(Math.random()*url_list.size());
            System.out.println(this.getName()+"removes the link nbr "+url_list.get(alea));
            url_list.remove(alea);
        }

    }


}

中:

代码语言:javascript
复制
CopyOnWriteArrayList<String> index = new CopyOnWriteArrayList( FileToList("/index/index.txt") );

        while( index.size() != 0)
        {
            List<Thread> tg = new ArrayList<Thread>();            
            for(int i=0;i<7;i++)
            {
                Thread t=new Thread(new Downloader(index, ""));
                t.start();
                tg.add(t);
            }

            for(Thread t: tg) 
                t.join();
        }

你知道如何摆脱ThreadException吗?谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-19 16:49:58

您对列表的访问没有同步。您有多个线程,即使init()方法是同步的,同步也是在线程实例上进行的,而不是在公共对象上,所以它是无用的。如果需要确保线程之间的互斥,则必须在公共对象上同步:

代码语言:javascript
复制
 public void init() // No synchronization here
    {
       synchronized(url_list) { // synchronize on a common object
        if (!url_list.isEmpty())
        {
            int alea = (int)(Math.random()*url_list.size());
            System.out.println(this.getName()+"removes the link nbr "+url_list.get(alea));
            url_list.remove(alea);
        }
      }

    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61896396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档