首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在多线程进程中访问单个集合

在多线程进程中访问单个集合
EN

Stack Overflow用户
提问于 2019-09-15 12:44:27
回答 3查看 233关注 0票数 0

我有一个关于多线程的问题。

如果我创建一个单独的集合(HasMap或list等),并在多线程(5)进程中访问相同的collecion,它会工作吗?

对Java多线程编码风格知之甚少。

EN

回答 3

Stack Overflow用户

发布于 2019-09-17 01:25:01

如果您在启动线程之前填充了该集合一次,然后所有线程都只从集合中读取,那么是的,简单的集合将会工作。但是,如果您的一些线程将数据放入/添加到集合中,而另一些线程读取数据,那么您要么需要使用线程安全集合(如ConcurrentHashMap或sumply Collections.synchronizedList(new ArrayList<>())),要么需要使用额外的同步,如synchronized块和/或Lock对象。

票数 1
EN

Stack Overflow用户

发布于 2019-09-17 11:17:12

因为你还在探索多线程,所以我假设你谈论的是java.util.XXX而不是java.util.concurrent.XXX。在处理不是线程安全的java.util集合时,一定要记住ConcurrentModificationException。如果你不是在修改一个集合,只是在读,那么没有问题。但是如果修改发生在其中一个线程中,你可能会得到ConcurrentModificationException异常。

试试下面的代码:

代码语言:javascript
复制
package my.package.concurrency_practice;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CollectionsAndThreads {
    private List<Integer> list = new ArrayList<>();

    public CollectionsAndThreads() {
        for (int i=0; i < 10_000_000; i++) {
            list.add(i);
        }
        System.out.println("Initialized with one million entries.");
    }

    public void addEntries() {

        System.out.print("Adding a million more entries ... ");
            for (int i = 10_000_001; i < 20_000_000; i++) {
                list.add(i);
            }
        System.out.println("Done.");
    }

    public void interateEntries() {
        Iterator iter = list.iterator();

        System.out.print("Interating through entries ... ");

            while (iter.hasNext()) {
                iter.next();
            }
        System.out.println("Done.");
    }

    public List<Integer> getList() {
        return list;
    }

    public static void main(String[] args) {
        CollectionsAndThreads test = new CollectionsAndThreads();

        System.out.println(test.getList().size());

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Inside thread: " + this.toString());
                test.addEntries();
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Inside thread: " + this.toString());
                test.interateEntries();
            }
        });

        thread1.start();
        thread2.start();
    }
}

你拿到java.util.ConcurrentModificationException了吗?

现在,这回答了您的问题。如何让上面的代码线程安全?您可以探索一下:-)

票数 0
EN

Stack Overflow用户

发布于 2019-09-16 19:28:38

这取决于你要做什么。操纵名单?删除元素?这个列表是临时的吗?是否只有4个线程是只读的,只有一个线程添加了某些内容?

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

https://stackoverflow.com/questions/57941218

复制
相关文章

相似问题

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