我正在尝试解决以下情况:我有一个自定义对象的嵌套列表。我必须并行处理外部列表,但内部列表对象必须按顺序处理。我为外部列表尝试了list.parallelstream(),为内部列表尝试了list.stream(),但它不起作用,内部列表的值在执行过程中被随机处理。我想过使用线程(ExecutorService),但不确定如何开始。下面是我的paralalStream代码片段:
处理列表的代码:
List<List<MyObject>> masterList = getMasterList();
masterList.parallelStream().forEach(innerList -> printSubList(innerList)); 填充列表的代码:
private static List<List<MyObject>> getMasterList() {
MyObject myObject1 = new MyObject(1,"ABC-1");
MyObject myObject2 = new MyObject(2,"ABC-2");
MyObject myObject3 = new MyObject(3,"ABC-3");
MyObject myObject4 = new MyObject(1,"XYZ-1");
MyObject myObject5 = new MyObject(2,"XYZ-2");
List<MyObject> innerList1 = new ArrayList<>();
innerList1.add(myObject1);
innerList1.add(myObject2);
innerList1.add(myObject3);
List<MyObject> innerList2 = new ArrayList<>();
innerList2.add(myObject4);
innerList2.add(myObject5);
List<List<MyObject>> masterList = new ArrayList<>();
masterList.add(innerList1);
masterList.add(innerList2);
return masterList;
}打印对象以验证:
private static Consumer<? super List<MyObject>> printSubList(List<MyObject> innerList) {
innerList.stream();
for(MyObject myObject : innerList) {
System.out.println("System Time = "+ System.currentTimeMillis()+" = "+myObject.getName()+" "+myObject.getId());
}
return null;
}我也可以使用Thread,但不确定在这种情况下如何使用。任何帮助都是非常感谢的。
这是我当前的输出:
System Time = 1603173228270 = ABC-3 3
System Time = 1603173228271 = XYZ-1 1
System Time = 1603173228272 = ABC-1 1
System Time = 1603173228272 = ABC-2 2
System Time = 1603173228272 = XYZ-2 2但我希望它是:
System Time = 1603173228270 = ABC-1 1
System Time = 1603173228271 = ABC-2 2
System Time = 1603173228272 = ABC-3 3
System Time = 1603173228270 = XYZ-1 1
System Time = 1603173228271 = XYZ-2 2发布于 2020-10-20 14:15:02
很高兴回复你。在这种情况下,我认为你的想法在多线程中是错误的。由于进程的后果在多线程或并行流中是不确定的,因此每个线程执行进程可能使用不同的时间。所以在这个过程中我们不能控制顺序,在例外的情况下,我们对它们做了一些逻辑,但这并不容易,而且也是不必要的。如果你真的想使用多个线程来处理这些数据。你可以试着关注this.Using Executors.newSingleThreadExecutor。Thread threadA = new Thread(()->{ System.out.println("A"); });
Thread threadB = new Thread(()->{ System.out.println("B"); });
Thread threadC = new Thread(() -> { System.out.println("C"); });
ExecutorService executors = Executors.newSingleThreadExecutor();
`executors.submit(threadA);
executors.submit(threadB);
executors.submit(threadC);
executors.shutdown();`
//答案总是A B C
发布于 2020-10-20 14:28:41
您的代码实际上是在并行“处理”外部列表,并按顺序“处理”内部列表。这只是因为您还在并行打印这些行,导致输出顺序混乱。
要解决这个问题,您应该将“处理对象”的逻辑与“打印对象”分开。与其让printSublist打印子列表,不如使用一个给定子列表的stringFromSublist方法,返回应该为该子列表打印的字符串。
private static String stringFromSublist(List<MyObject> innerList) {
return innerList.stream()
.map(myObject -> "System Time = "+
System.nanoTime()+ // nanoTime gives you more resolution
" = "+myObject.getName()+
" "+myObject.getId())
.collect(Collectors.joining("\n"));
}现在您可以在使用forEachOrdered之前使用map
masterList.parallelStream()
.map(Main::stringFromSublist) // assuming stringFromSublist is in a class called Main
.forEachOrdered(System.out::println);map将是并行的。forEachOrdered将是连续的。
输出示例:
System Time = 20136256197640 = ABC-1 1
System Time = 20136285091800 = ABC-2 2
System Time = 20136285104398 = ABC-3 3
System Time = 20136256536459 = XYZ-1 1
System Time = 20136284789960 = XYZ-2 2https://stackoverflow.com/questions/64439077
复制相似问题