gpt4 book ai didi

java - 是否可以仅同步 java 流中的终端方法调用?

转载 作者:行者123 更新时间:2023-12-01 09:16:39 25 4
gpt4 key购买 nike

让我们考虑可以从不同线程访问的集合。我正在寻找一种线程安全的方法来使用 java 流操作集合。

由于所有中间流操作都是惰性的,所以真正的作业只能在终端方法中执行。我只能同步终端方法调用。

那么,代码是否线程安全:

public void print(Collection<String> list){
Stream stream = list.stream();
synchronized(this){
stream.forEach(p -> System.out.println(p));
}
}

最佳答案

当然,这取决于您的应用程序 synchronized(this) 是否足以(或根本必要)来阻止在 Stream 遍历期间对源 Collection 进行操作。

关于惰性,确切的行为取决于源集合。考虑the contract of Collection.spliterator() :

In order to preserve expected laziness behavior for the stream() and parallelStream() methods, spliterators should either have the characteristic of IMMUTABLE or CONCURRENT, or be late-binding. If none of these is practical, the overriding class should describe the spliterator's documented policy of binding and structural interference, and should override the stream() and parallelStream() methods to create streams using a Supplier of the spliterator, as in:

Stream<E> s = StreamSupport.stream(() -> spliterator(), spliteratorCharacteristics)

These requirements ensure that streams produced by the stream() and parallelStream() methods will reflect the contents of the collection as of initiation of the terminal stream operation.

为了缩短这一点,上面列出的所有变体都意味着允许在开始终端操作之前对源 Collection 进行修改(当然,不包括 IMMUTABLE spliterators),并将由 Stream 操作反射(reflect).

因此,如果您的应用程序保护对源列表的所有操作,以防止在执行终端操作时对源列表进行操作,那么您就安全了。但请注意,接收列表作为参数,但在 this 上进行同步的方法看起来并没有正确保护列表。只是为了明确一点:所有线程必须在同一对象上同步以保护特定的共享资源。

但抛开这一点,假设操作 list 的所有线程都将在 listLock 上正确同步,则以下代码将起作用:

Stream stream = list.stream()
.intermediateOp1(…)
.intermediateOp2(…);

synchronized(listLock){
stream.forEach(p -> System.out.println(p));
}

但这毫无意义。正如您自己所说,这样做的原因是,将中间操作链接到流不会导致任何实际处理。这是一个非常便宜的东西,因此将其从 protected 代码部分中排除只意味着持有锁的时间可能会相差几纳秒。

你几乎不会注意到有什么不同

synchronized(listLock) {
list.stream()
.intermediateOp1(…)
.intermediateOp2(…)
.forEach(p -> System.out.println(p));
}

因为无论如何,大部分时间都花在 forEach 中。

关于java - 是否可以仅同步 java 流中的终端方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40505243/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com