Identifying resource-using streams

Zhong Yu zhong.j.yu at gmail.com
Mon Apr 21 20:32:49 UTC 2014


On Mon, Apr 21, 2014 at 1:42 AM, Timo Kinnunen <timo.kinnunen at gmail.com> wrote:
> Regarding: “Which is the overwhelmingly common case.  Most stream sources are
> collections or other non-resource-holding sources.  Most streams are
> created and consumed in the same place.  This is how the API was
> designed, how all the examples work, and by all evidence, how it is
> being used.”
>
>
> You keep saying that, and maybe there’s a lot of ad-hoc Streams use that I don’t even think about, but almost all of the cases where I plan to use Streams involve reading the contents of directories, reading the contents of files or reading the contents of JAR files. All are cases where resources are involved and the processing too complicated to fit in a single method.
>
>
>
>
> Re: “The alternate argument is that every terminal should close() its source,
> regardless of whether that does anything or not.  The EG considered
> this, and decided that this was a violation of the rule: "the party
> acquiring the resource has responsibility for releasing the resource."
> (This is the same reason reading the last line of a file does not close
> it.)”
>
>
> Using things like a Supplier<FileInputStream> it would be very easy to delay the resource acquisition so that it could happen inside the terminal method, making every terminal naturally responsible for releasing resources.

I'm against piggybacking close() on Stream. The core semantics of
Stream interface are transformation and termination, having nothing to
do with resource allocation/deallocation.

However, it would be even worse to do close() on termination,
complicating its semantics. It's solving pollution with more
pollution. Besides, termination cannot be reliably reached.

It seems that the best practice is still that whoever explicitly
acquired a resource is responsible to explicitly free the resource.
Unfortunately the current design of Stream makes it a little difficult
to know whether a resource is acquired. If your API emits Streams and
you don't like the current design, you may have to provide your own
abstraction. There are a number of ways to do this, and we don't know
a priori which one is the best for most use cases.

Zhong Yu

PS I find nothing wrong with Timo's tone; it sounds to me perfectly
constructive.

>
>
> All of the above brings up another unfortunate feature of the API: a Stream is very close to being an immutable stateless builder for stream-like processing but it is neither immutable nor stateless.
>
>
> If Stream was immutable and stateless then you would be able to reuse, rerun and combine Streams freely and all the processing would be happening in a single place, inside terminals. Because where else could it happen?
>
>
>
>
> --
> Have a nice day,
> Timo.
>
> Sent from Windows Mail
>
>
>
>
>
> From: Brian Goetz
> Sent: ‎Sunday‎, ‎April‎ ‎20‎, ‎2014 ‎17‎:‎08
> To: Timo Kinnunen, Erik Costlow, lambda-dev at openjdk.java.net
>
>
>
>
>
>> Regarding: “This was a tradeoff to bring IO-wrapping streams into the
>> story without polluting the majority of streams with resource management
>> considerations (since most streams do not hold resources.)”
>>
>> You don’t know that, really.
>>
>> Only in the case where a Stream is created and used within a small
>> method and it very obviously doesn’t deal with IO or other resources is
>> it safe to not close it.
>
> Which is the overwhelmingly common case.  Most stream sources are
> collections or other non-resource-holding sources.  Most streams are
> created and consumed in the same place.  This is how the API was
> designed, how all the examples work, and by all evidence, how it is
> being used.
>
>> It’s unfortunate that the API makes not
>> releasing resources the more convenient usage pattern because that’s
>> going to guarantee that such use patterns will make their way into
>> situations where there are resources to be released.
>
> No, polluting every use of streams with resource management when only a
> tiny fraction will hold resources would have been unfortunate.  Making
> resources release impossible would have been unfortunate.
>
> The alternate argument is that every terminal should close() its source,
> regardless of whether that does anything or not.  The EG considered
> this, and decided that this was a violation of the rule: "the party
> acquiring the resource has responsibility for releasing the resource."
> (This is the same reason reading the last line of a file does not close
> it.)
>


More information about the lambda-dev mailing list