<div dir="ltr">Could you explain the "closeable queue"? Indeed, I want "close" queue and my implementation is <br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">queueMap.remove(customerId) </blockquote><div><br></div><div>I was sure my solution is genius rather than obscure :)  </div><div>But I would like to learn another way to achieve closeable queue</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">wt., 9 lip 2024 o 17:43 Robert Engels <<a href="mailto:robaho@icloud.com">robaho@icloud.com</a>> napisał(a):<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;">As an aside, that seems like a much more complicated and obscure design than using closable queues.<br><div><br><blockquote type="cite"><div>On Jul 9, 2024, at 10:24 AM, Michal Domagala <<a href="mailto:outsider404@gmail.com" target="_blank">outsider404@gmail.com</a>> wrote:</div><br><div><div dir="ltr">Indeed, for 25+ years thread is GC root.<div>But for 3+ years virtual threads are present and they are documented as ephemeral.</div><div>Developers are used to alive threads and virtual, alive threads are not confusing. But virtual, alive threads documented as ephemeral are confusing.</div><div>Moreover, the idea that VT from Executors API is GCed but from Thread API not looks inconsistent. But it is low confusion. Working against documentation is high confusion.</div><div><br></div><div>Let's consider my case. I take 1000 Kafka events for concrete people each poll. 90% of events are ignored (not my customers), 10% are processed (my customers), but each event must be acked.</div><div>Each customer has a blocking queue. 10% is distributed to proper queues. Each queue has a VT, which processes the event and finally ack the event.</div><div>From time to time customers are off. Their blocking queues are thrown away. </div><div>There is a chance that at the same moment the customer is off, new poll come with customer events. Kafka listener put event to customer queue and expects VT will ack the event.</div><div>VT can't be stopped by the "customer-off" process, because new events may come to the blocking queue anytime.</div><div><br></div><div>Race can be solved without synchronization. GC "knows" when the blocking queue is not visible by Kafka listener thread and "stops" the VT by reclaiming its resources.<br><br>I hope this example is clear enough to see that reclaiming VT resources by GC is simple and automatic when manual solution requires thread synchronization and is prone to errors.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">wt., 9 lip 2024 o 16:24 Alan Bateman <<a href="mailto:Alan.Bateman@oracle.com" target="_blank">Alan.Bateman@oracle.com</a>> napisał(a):<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 09/07/2024 12:51, Michal Domagala wrote:<br>
> Thanks for valuable observability context<br>
><br>
> As I understand, initially VT created by Thread API was not observable <br>
> in thread dump and VT created by Executors API was observable. It was <br>
> confusing and now both kinds of VT are observable. Make sense.<br>
> But observability is reached by strong reference. VT created by Thread <br>
> API are strongly referenced until stop and not GC'ed until stop and VT <br>
> created by Executors API are not referenced at all and GC'ed when not <br>
> reachable, regardless of being stopped or not. That's not OK and much <br>
> worse than previous confusion.<br>
<br>
An ExecutorService implementation has to keep a reference to each <br>
task/thread because of the shutdownNow and close method. There are other <br>
thread groupings that arise when using structured concurrency that <br>
require a thread executing a main task wait for threads executing <br>
subtasks to finish executing.<br>
<br>
As things stand I don't expect there will be much confusion. For 25+ <br>
years, a started thread is alive (and strongly reachable) until it <br>
terminates. Having virtual thread work mostly the same shouldn't be a <br>
surprise. As I said, the door hasn't been closed on introducing some <br>
notion of ephemeral thread in the future. It's not really feasible right <br>
now because of finalization and because of several issues related to <br>
cleaner actions and explicit APIs to keep some object reachable until a <br>
thread gets to some point in its execution. So there is more to this <br>
than just observability (and yes of course observability could traverse <br>
other reference types if needed).<br>
<br>
As regards the thread counting in the root container when running with <br>
the undocumented system property jdk.trackAllThreads is set to false. <br>
That is the count of the live (started but not terminated) threads in <br>
that thread grouping. It is a left over from when we will mulling over <br>
what the right default should be (reporting a thread count when you <br>
can't list the threads has some value).<br>
<br>
-Alan<br>
</blockquote></div>
</div></blockquote></div><br></div></blockquote></div>