我有一个关于多线程的问题。
如果我创建一个单独的集合(HasMap或list等),并在多线程(5)进程中访问相同的collecion,它会工作吗?
对Java多线程编码风格知之甚少。
发布于 2019-09-17 01:25:01
如果您在启动线程之前填充了该集合一次,然后所有线程都只从集合中读取,那么是的,简单的集合将会工作。但是,如果您的一些线程将数据放入/添加到集合中,而另一些线程读取数据,那么您要么需要使用线程安全集合(如ConcurrentHashMap或sumply Collections.synchronizedList(new ArrayList<>())),要么需要使用额外的同步,如synchronized块和/或Lock对象。
发布于 2019-09-17 11:17:12
因为你还在探索多线程,所以我假设你谈论的是java.util.XXX而不是java.util.concurrent.XXX。在处理不是线程安全的java.util集合时,一定要记住ConcurrentModificationException。如果你不是在修改一个集合,只是在读,那么没有问题。但是如果修改发生在其中一个线程中,你可能会得到ConcurrentModificationException异常。
试试下面的代码:
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了吗?
现在,这回答了您的问题。如何让上面的代码线程安全?您可以探索一下:-)
发布于 2019-09-16 19:28:38
这取决于你要做什么。操纵名单?删除元素?这个列表是临时的吗?是否只有4个线程是只读的,只有一个线程添加了某些内容?
https://stackoverflow.com/questions/57941218
复制相似问题