我正在构建一个需要创建共享ArrayList对象的应用程序。它是一个多线程环境,因此所有线程都应写入同一列表。
我试图创建一个列表对象并传递给executorservice,但这将创建同一列表的多个副本,最后我只看到列表中添加了一项。
注意:我只关心异步编写列表。我的阅读已同步。
//If you want to use the following:
Provider.of<ButtonData>(context, listen: false).selectedButton = xyz;
//You need to declare a setter named `selectedButton` in your ButtonData
// class. Like so:
set selectedButton(Button button) {
_selectedButton = button;
notifyListeners();
}
//Currently, in your ButtonData class, you have not declared a setter,
// instead you created a method there for updating the value.
//This one.
void setSelectedItem(Button s) {
_selectedButton = s;
notifyListeners();
}
//If you want to use this method for updating your `selectedButton` value,
// you can use the following line of code.
Provider.of<ButtonData>(context, listen: false).setSelectedItem(xyz);
如何使所有线程使用/写入同一List对象?
我是多线程技术的新手,将不胜感激。
谢谢。
更新:我尝试使用Collections.syncronizedList,但它仍然对我不起作用。可能是我没有正确使用它
public class main{
public static void main(String[] args)
{
ExecutorService taskExec = Executors.newFixedThreadPool(count);
List<JsonDocument> documents = new ArrayList<JsonDocument>();
// this seems to be incorrect
taskExec.submit(new test(documents, size));
}
}
class test implements Runnable{
// this class will add JsonDocuments to list object
}
请在这里纠正我。
答案 0 :(得分:2)
Collections.syncronizedList
应该可以完成工作,但是您的代码存在一些问题:
taskExec.submit(new test(documents, size));
for (JsonDocument json : documents) {
System.out.println(json.toString());
}
while(!taskExec.isTerminated()) {
taskExec.shutdown();
}
您提交可运行对象,但不等待终止 打印列表
while(!taskExec.isTerminated())
不是
等待终止的正确方法
这是修改后的代码:
taskExec.submit(new test(documents, size));
taskExec.awaitTermination(1, TimeUnit.MINUTES);// wait a minute for termination
for (JsonDocument json : documents) {
System.out.println(json.toString());
}
// This should be inside a finally block
taskExec.shutdown();
答案 1 :(得分:1)
for-loop
取决于线程执行的操作。您必须等待所有线程完成执行。您可以使用Eugen建议的taskExec.awaitTermination
。但是很难提出awaitTermination
超时时间,您可以传递一些大的值,但是解决方案无法很好地扩展。
如果您使用的是Java 8或更高版本,请使用CompletableFuture
:
CompletableFuture.runAsync(new test(documents, size), taskExec2)
.thenAccept(documents -> documents.forEach(doc -> System.out.print(doc.toString())));
如果您使用的是Java 7,则可以使用Future
Future<Void> future = taskExec.submit(new test(documents, size));
submit.get(); // blocking operation
// your logic for-loop etc.
测试班:
class test implements Callable<Void> {
// constructor etc.
public Void call() {
// your business logic
return null;
}
}
请注意, syncedList的结果是“ synchronized”,而不是“ concurrent”。许多基于索引的List操作本身不是原子的,这是一个基本问题,需要成为更大的互斥结构的一部分。