Customized ForkJoinPool constructor

classic Classic list List threaded Threaded
24 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Customized ForkJoinPool constructor

Doug Lea

As usage contexts of ForkJoinPool increase, it's becoming harder to
ensure that internal settings and policies are equally good across all
of them. The defaults generally work well (especially for the common pool),
but it's a bad omen that advanced users are resorting to clever and
weird hacks; even including using Unsafe or reflection to modify internals.
(For a disconcertingly cool example, see the APGAS framework at
https://github.com/x10-lang/x10/tree/master/apgas)

The only model for pool customization in j.u.c is ThreadPoolExecutor.
The proposed new ForkJoinPool constructor accepts parameters that are
mostly identical to TPE. (It took a fair amount of internal rework to
enable this.) Unlike TPE, these settings cannot be changed dynamically.

Comments would be welcome. The javadoc is pasted below, and at
http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/ForkJoinPool.html

Experience reports would be even more welcome.
You can run on either jdk8 or early-access jdk9 by getting jar
(http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166.jar)
or building (see http://gee.cs.oswego.edu/dl/concurrency-interest/index.html)
Warning: soon we will need to split jdk8 and jdk9 repos to cope with jigsaw etc.

... pasting ...


         public ForkJoinPool(int parallelism,
                             ForkJoinPool.ForkJoinWorkerThreadFactory factory,
                             Thread.UncaughtExceptionHandler handler,
                             boolean asyncMode,
                             int corePoolSize,
                             int maximumPoolSize,
                             int minimumRunnable,
                             boolean rejectOnSaturation,
                             long keepAliveTime,
                             TimeUnit unit)

         Creates a ForkJoinPool with the given parameters.

         Parameters:
             parallelism - the parallelism level. For default value, use
Runtime.availableProcessors().
             factory - the factory for creating new threads. For default value,
use defaultForkJoinWorkerThreadFactory.
             handler - the handler for internal worker threads that terminate
due to unrecoverable errors encountered while executing tasks. For default
value, use null.
             asyncMode - if true, establishes local first-in-first-out
scheduling mode for forked tasks that are never joined. This mode may be more
appropriate than default locally stack-based mode in applications in which
worker threads only process event-style asynchronous tasks. For default value,
use false.
             corePoolSize - the number of threads to keep in the pool (unless
timed out after an elapsed keep-alive). Normally (and by default) this is the
same value as the parallelism level, but may be set to a larger value to reduce
dynamic overhead if tasks regularly block. Using a smaller value (for example 0)
has the same effect as the default.
             maximumPoolSize - the maximum number of threads allowed. When the
maximum is reached, attempts to replace blocked threads fail. (However, because
creation and termination of different threads may overlap, and may be managed by
the given thread factory, this value may be transiently exceeded.) The default
for the common pool is 256 plus the parallelism level. Using a value (for
example Integer.MAX_VALUE) larger than the implementation's total thread limit
has the same effect as using this limit.
             minimumRunnable - the minimum allowed number of core threads not
blocked by a join or ForkJoinPool.ManagedBlocker. To ensure progress, when too
few unblocked threads exist and unexecuted tasks may exist, new threads are
constructed, up to the given maximumPoolSize. For the default value, use 1, that
ensures liveness. A larger value might improve throughput in the presence of
blocked activities, but might not, due to increased overhead. A value of zero
may be acceptable when submitted tasks cannot have dependencies requiring
additional threads.
             rejectOnSaturation - if true, attempts to create more than the
maximum total allowed threads throw RejectedExecutionException. Otherwise, the
pool continues to operate, but with fewer than the target number of runnable
threads, so might not ensure progress. For default value, use true.
             keepAliveTime - the elapsed time since last use before a thread is
terminated (and then later replaced if needed). For the default value, use 60,
TimeUnit.SECONDS.
             unit - the time unit for the keepAliveTime argument
         Throws:
             IllegalArgumentException - if parallelism is less than or equal to
zero, or is greater than implementation limit, or if maximumPoolSize is less
than parallelism, of if the keepAliveTime is less than or equal to zero.
             NullPointerException - if the factory is null
             SecurityException - if a security manager exists and the caller is
not permitted to modify threads because it does not hold
RuntimePermission("modifyThread")
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Roger Riggs
Hi Doug,

Is there any chance I can nudge/encourage you to switch the two
arguments for keepAliveTime
to a single argument using java.time.Duration?  Though it was not
introduced until JDK 8 it
is a much nicer packaging of a duration.

Roger


On 3/14/16 9:56 AM, Doug Lea wrote:

>
> As usage contexts of ForkJoinPool increase, it's becoming harder to
> ensure that internal settings and policies are equally good across all
> of them. The defaults generally work well (especially for the common
> pool),
> but it's a bad omen that advanced users are resorting to clever and
> weird hacks; even including using Unsafe or reflection to modify
> internals.
> (For a disconcertingly cool example, see the APGAS framework at
> https://github.com/x10-lang/x10/tree/master/apgas)
>
> The only model for pool customization in j.u.c is ThreadPoolExecutor.
> The proposed new ForkJoinPool constructor accepts parameters that are
> mostly identical to TPE. (It took a fair amount of internal rework to
> enable this.) Unlike TPE, these settings cannot be changed dynamically.
>
> Comments would be welcome. The javadoc is pasted below, and at
> http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/ForkJoinPool.html 
>
>
> Experience reports would be even more welcome.
> You can run on either jdk8 or early-access jdk9 by getting jar
> (http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166.jar)
> or building (see
> http://gee.cs.oswego.edu/dl/concurrency-interest/index.html)
> Warning: soon we will need to split jdk8 and jdk9 repos to cope with
> jigsaw etc.
>
> ... pasting ...
>
>
>         public ForkJoinPool(int parallelism,
> ForkJoinPool.ForkJoinWorkerThreadFactory factory,
>                             Thread.UncaughtExceptionHandler handler,
>                             boolean asyncMode,
>                             int corePoolSize,
>                             int maximumPoolSize,
>                             int minimumRunnable,
>                             boolean rejectOnSaturation,
>                             long keepAliveTime,
>                             TimeUnit unit)
>
>         Creates a ForkJoinPool with the given parameters.
>
>         Parameters:
>             parallelism - the parallelism level. For default value,
> use Runtime.availableProcessors().
>             factory - the factory for creating new threads. For
> default value, use defaultForkJoinWorkerThreadFactory.
>             handler - the handler for internal worker threads that
> terminate due to unrecoverable errors encountered while executing
> tasks. For default value, use null.
>             asyncMode - if true, establishes local first-in-first-out
> scheduling mode for forked tasks that are never joined. This mode may
> be more appropriate than default locally stack-based mode in
> applications in which worker threads only process event-style
> asynchronous tasks. For default value, use false.
>             corePoolSize - the number of threads to keep in the pool
> (unless timed out after an elapsed keep-alive). Normally (and by
> default) this is the same value as the parallelism level, but may be
> set to a larger value to reduce dynamic overhead if tasks regularly
> block. Using a smaller value (for example 0) has the same effect as
> the default.
>             maximumPoolSize - the maximum number of threads allowed.
> When the maximum is reached, attempts to replace blocked threads fail.
> (However, because creation and termination of different threads may
> overlap, and may be managed by the given thread factory, this value
> may be transiently exceeded.) The default for the common pool is 256
> plus the parallelism level. Using a value (for example
> Integer.MAX_VALUE) larger than the implementation's total thread limit
> has the same effect as using this limit.
>             minimumRunnable - the minimum allowed number of core
> threads not blocked by a join or ForkJoinPool.ManagedBlocker. To
> ensure progress, when too few unblocked threads exist and unexecuted
> tasks may exist, new threads are constructed, up to the given
> maximumPoolSize. For the default value, use 1, that ensures liveness.
> A larger value might improve throughput in the presence of blocked
> activities, but might not, due to increased overhead. A value of zero
> may be acceptable when submitted tasks cannot have dependencies
> requiring additional threads.
>             rejectOnSaturation - if true, attempts to create more than
> the maximum total allowed threads throw RejectedExecutionException.
> Otherwise, the pool continues to operate, but with fewer than the
> target number of runnable threads, so might not ensure progress. For
> default value, use true.
>             keepAliveTime - the elapsed time since last use before a
> thread is terminated (and then later replaced if needed). For the
> default value, use 60, TimeUnit.SECONDS.
>             unit - the time unit for the keepAliveTime argument
>         Throws:
>             IllegalArgumentException - if parallelism is less than or
> equal to zero, or is greater than implementation limit, or if
> maximumPoolSize is less than parallelism, of if the keepAliveTime is
> less than or equal to zero.
>             NullPointerException - if the factory is null
>             SecurityException - if a security manager exists and the
> caller is not permitted to modify threads because it does not hold
> RuntimePermission("modifyThread")
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Henrik Johansson-8
Hi,

As a casual user but with occasionally complex needs a builder would be extremely nice to have.

I understand that stdlib may not be the place but if some frequent usage patterns can be found perhaps it can be included as well?

On Mon, Mar 14, 2016 at 3:57 PM Roger Riggs <[hidden email]> wrote:

Hi Doug,

Is there any chance I can nudge/encourage you to switch the two
arguments for keepAliveTime
to a single argument using java.time.Duration?  Though it was not
introduced until JDK 8 it
is a much nicer packaging of a duration.

Roger


On 3/14/16 9:56 AM, Doug Lea wrote:
>
> As usage contexts of ForkJoinPool increase, it's becoming harder to
> ensure that internal settings and policies are equally good across all
> of them. The defaults generally work well (especially for the common
> pool),
> but it's a bad omen that advanced users are resorting to clever and
> weird hacks; even including using Unsafe or reflection to modify
> internals.
> (For a disconcertingly cool example, see the APGAS framework at
> https://github.com/x10-lang/x10/tree/master/apgas)
>
> The only model for pool customization in j.u.c is ThreadPoolExecutor.
> The proposed new ForkJoinPool constructor accepts parameters that are
> mostly identical to TPE. (It took a fair amount of internal rework to
> enable this.) Unlike TPE, these settings cannot be changed dynamically.
>
> Comments would be welcome. The javadoc is pasted below, and at
> http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/ForkJoinPool.html
>
>
> Experience reports would be even more welcome.
> You can run on either jdk8 or early-access jdk9 by getting jar
> (http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166.jar)
> or building (see
> http://gee.cs.oswego.edu/dl/concurrency-interest/index.html)
> Warning: soon we will need to split jdk8 and jdk9 repos to cope with
> jigsaw etc.
>
> ... pasting ...
>
>
>         public ForkJoinPool(int parallelism,
> ForkJoinPool.ForkJoinWorkerThreadFactory factory,
>                             Thread.UncaughtExceptionHandler handler,
>                             boolean asyncMode,
>                             int corePoolSize,
>                             int maximumPoolSize,
>                             int minimumRunnable,
>                             boolean rejectOnSaturation,
>                             long keepAliveTime,
>                             TimeUnit unit)
>
>         Creates a ForkJoinPool with the given parameters.
>
>         Parameters:
>             parallelism - the parallelism level. For default value,
> use Runtime.availableProcessors().
>             factory - the factory for creating new threads. For
> default value, use defaultForkJoinWorkerThreadFactory.
>             handler - the handler for internal worker threads that
> terminate due to unrecoverable errors encountered while executing
> tasks. For default value, use null.
>             asyncMode - if true, establishes local first-in-first-out
> scheduling mode for forked tasks that are never joined. This mode may
> be more appropriate than default locally stack-based mode in
> applications in which worker threads only process event-style
> asynchronous tasks. For default value, use false.
>             corePoolSize - the number of threads to keep in the pool
> (unless timed out after an elapsed keep-alive). Normally (and by
> default) this is the same value as the parallelism level, but may be
> set to a larger value to reduce dynamic overhead if tasks regularly
> block. Using a smaller value (for example 0) has the same effect as
> the default.
>             maximumPoolSize - the maximum number of threads allowed.
> When the maximum is reached, attempts to replace blocked threads fail.
> (However, because creation and termination of different threads may
> overlap, and may be managed by the given thread factory, this value
> may be transiently exceeded.) The default for the common pool is 256
> plus the parallelism level. Using a value (for example
> Integer.MAX_VALUE) larger than the implementation's total thread limit
> has the same effect as using this limit.
>             minimumRunnable - the minimum allowed number of core
> threads not blocked by a join or ForkJoinPool.ManagedBlocker. To
> ensure progress, when too few unblocked threads exist and unexecuted
> tasks may exist, new threads are constructed, up to the given
> maximumPoolSize. For the default value, use 1, that ensures liveness.
> A larger value might improve throughput in the presence of blocked
> activities, but might not, due to increased overhead. A value of zero
> may be acceptable when submitted tasks cannot have dependencies
> requiring additional threads.
>             rejectOnSaturation - if true, attempts to create more than
> the maximum total allowed threads throw RejectedExecutionException.
> Otherwise, the pool continues to operate, but with fewer than the
> target number of runnable threads, so might not ensure progress. For
> default value, use true.
>             keepAliveTime - the elapsed time since last use before a
> thread is terminated (and then later replaced if needed). For the
> default value, use 60, TimeUnit.SECONDS.
>             unit - the time unit for the keepAliveTime argument
>         Throws:
>             IllegalArgumentException - if parallelism is less than or
> equal to zero, or is greater than implementation limit, or if
> maximumPoolSize is less than parallelism, of if the keepAliveTime is
> less than or equal to zero.
>             NullPointerException - if the factory is null
>             SecurityException - if a security manager exists and the
> caller is not permitted to modify threads because it does not hold
> RuntimePermission("modifyThread")
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Martin Buchholz-3
In reply to this post by Roger Riggs
On Mon, Mar 14, 2016 at 7:48 AM, Roger Riggs <[hidden email]> wrote:
> Hi Doug,
>
> Is there any chance I can nudge/encourage you to switch the two arguments
> for keepAliveTime
> to a single argument using java.time.Duration?  Though it was not introduced
> until JDK 8 it
> is a much nicer packaging of a duration.

Perhaps, but there is a long tradition of using (long, TimeUnit)
parameter pairs, an engineering compromise; and one is tempted to wait
for value types to be added in jdkN+1.  But it looks like Duration is
"value-type-ready".
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Kirk Pepperdine
In reply to this post by Henrik Johansson-8
Hi,

A number of us have had discussions with Stuart Marks regarding the usability of parallel streams in general compute environments. IMHO, F-J and hence parallel streams have been completely unusable in these types of environments even for problems that are a good fit for F-J. At issue is that there doesn’t exist any means to have the workload describe the parameters under which is should function and have it adapt to changing conditions in the runtime. IME, to blindly throw a workload at F-J (via parallel streams) has been a recipe for disaster. In December I suggested to Stuart that we be allowed to attach some sort of policy to the job so that there is some control or ability to adapt after the job has been launched. Stuart, being much smarter than me, rejected that solution but it did get him thinking that something more is needed to help workloads be able to have more control over their own fate after beng submitted to F-J (again via parallel streams). We get to talk to him to see what type of progress has been made at jCrete. That said, I’m wondering if there is some cross-over here between the usability issues I’m seeing and the problems that are trying to be hacked around frameworks such as APGAS.

Kind regards,
Kirk Pepperdine

On Mar 14, 2016, at 4:35 PM, Henrik Johansson <[hidden email]> wrote:

Hi,

As a casual user but with occasionally complex needs a builder would be extremely nice to have.

I understand that stdlib may not be the place but if some frequent usage patterns can be found perhaps it can be included as well?

On Mon, Mar 14, 2016 at 3:57 PM Roger Riggs <[hidden email]> wrote:

Hi Doug,

Is there any chance I can nudge/encourage you to switch the two
arguments for keepAliveTime
to a single argument using java.time.Duration?  Though it was not
introduced until JDK 8 it
is a much nicer packaging of a duration.

Roger


On 3/14/16 9:56 AM, Doug Lea wrote:
>
> As usage contexts of ForkJoinPool increase, it's becoming harder to
> ensure that internal settings and policies are equally good across all
> of them. The defaults generally work well (especially for the common
> pool),
> but it's a bad omen that advanced users are resorting to clever and
> weird hacks; even including using Unsafe or reflection to modify
> internals.
> (For a disconcertingly cool example, see the APGAS framework at
> https://github.com/x10-lang/x10/tree/master/apgas)
>
> The only model for pool customization in j.u.c is ThreadPoolExecutor.
> The proposed new ForkJoinPool constructor accepts parameters that are
> mostly identical to TPE. (It took a fair amount of internal rework to
> enable this.) Unlike TPE, these settings cannot be changed dynamically.
>
> Comments would be welcome. The javadoc is pasted below, and at
> http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/ForkJoinPool.html
>
>
> Experience reports would be even more welcome.
> You can run on either jdk8 or early-access jdk9 by getting jar
> (http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166.jar)
> or building (see
> http://gee.cs.oswego.edu/dl/concurrency-interest/index.html)
> Warning: soon we will need to split jdk8 and jdk9 repos to cope with
> jigsaw etc.
>
> ... pasting ...
>
>
>         public ForkJoinPool(int parallelism,
> ForkJoinPool.ForkJoinWorkerThreadFactory factory,
>                             Thread.UncaughtExceptionHandler handler,
>                             boolean asyncMode,
>                             int corePoolSize,
>                             int maximumPoolSize,
>                             int minimumRunnable,
>                             boolean rejectOnSaturation,
>                             long keepAliveTime,
>                             TimeUnit unit)
>
>         Creates a ForkJoinPool with the given parameters.
>
>         Parameters:
>             parallelism - the parallelism level. For default value,
> use Runtime.availableProcessors().
>             factory - the factory for creating new threads. For
> default value, use defaultForkJoinWorkerThreadFactory.
>             handler - the handler for internal worker threads that
> terminate due to unrecoverable errors encountered while executing
> tasks. For default value, use null.
>             asyncMode - if true, establishes local first-in-first-out
> scheduling mode for forked tasks that are never joined. This mode may
> be more appropriate than default locally stack-based mode in
> applications in which worker threads only process event-style
> asynchronous tasks. For default value, use false.
>             corePoolSize - the number of threads to keep in the pool
> (unless timed out after an elapsed keep-alive). Normally (and by
> default) this is the same value as the parallelism level, but may be
> set to a larger value to reduce dynamic overhead if tasks regularly
> block. Using a smaller value (for example 0) has the same effect as
> the default.
>             maximumPoolSize - the maximum number of threads allowed.
> When the maximum is reached, attempts to replace blocked threads fail.
> (However, because creation and termination of different threads may
> overlap, and may be managed by the given thread factory, this value
> may be transiently exceeded.) The default for the common pool is 256
> plus the parallelism level. Using a value (for example
> Integer.MAX_VALUE) larger than the implementation's total thread limit
> has the same effect as using this limit.
>             minimumRunnable - the minimum allowed number of core
> threads not blocked by a join or ForkJoinPool.ManagedBlocker. To
> ensure progress, when too few unblocked threads exist and unexecuted
> tasks may exist, new threads are constructed, up to the given
> maximumPoolSize. For the default value, use 1, that ensures liveness.
> A larger value might improve throughput in the presence of blocked
> activities, but might not, due to increased overhead. A value of zero
> may be acceptable when submitted tasks cannot have dependencies
> requiring additional threads.
>             rejectOnSaturation - if true, attempts to create more than
> the maximum total allowed threads throw RejectedExecutionException.
> Otherwise, the pool continues to operate, but with fewer than the
> target number of runnable threads, so might not ensure progress. For
> default value, use true.
>             keepAliveTime - the elapsed time since last use before a
> thread is terminated (and then later replaced if needed). For the
> default value, use 60, TimeUnit.SECONDS.
>             unit - the time unit for the keepAliveTime argument
>         Throws:
>             IllegalArgumentException - if parallelism is less than or
> equal to zero, or is greater than implementation limit, or if
> maximumPoolSize is less than parallelism, of if the keepAliveTime is
> less than or equal to zero.
>             NullPointerException - if the factory is null
>             SecurityException - if a security manager exists and the
> caller is not permitted to modify threads because it does not hold
> RuntimePermission("modifyThread")
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

signature.asc (507 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Doug Lea
In reply to this post by Doug Lea

A few notes and replies...

Thanks to Viktor for complaining about just using a boolean for saturation
control. Now changed to accept a predicate that also provides a callback for
arbitrary processing on saturation:

      * @param saturate if nonnull, a predicate invoked upon attempts
      * to create more than the maximum total allowed threads.  By
      * default, when a thread is about to block on a join or {@link
      * ManagedBlocker}, but cannot be replaced because the
      * maximumPoolSize would be exceeded, a {@link
      * RejectedExecutionException} is thrown.  But if this predicate
      * returns {@code true}, then no exception is thrown, so the pool
      * continues to operate with fewer than the target number of
      * runnable threads, which might not ensure progress.
      *

> On 03/14/2016 10:48 AM, Roger Riggs wrote:
>> Is there any chance I can nudge/encourage you to switch the two arguments
>> for keepAliveTime to a single argument using java.time.Duration?  Though it
>> was not introduced until JDK 8 it is a much nicer packaging of a duration.
>>

As Martin mentioned, the initial main rationale for TimeUnit was to avoid
allocation and GC when dealing with small durations used in timeouts and
timings. When value types appear, we'll definitely want to revisit this.
But for now left alone for uniformity with all other j.u.c APIs.

> On 03/14/2016 10:54 AM, Chris Purcell wrote:
>> Wouldn't a builder be appropriate here?
>>

Maybe, but the convention is to use factories for all common cases in
class Executors, leaving only advanced users to deal with plain
constructors in concrete classes. And done here for cowardly uniformity
as well.

-Doug



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Markus KARG

Sorry if I chime in or this already was discussed, but I did not follow the thread from the beginning: I think it would be great if a work stealing executor could be configured for a maximum global queue length, so when adding more work it will throw RejectedExecutionException in case the global queue length is exceeded but no more workers may be allocated.

 

-Markus

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 17:07
An: [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

 

A few notes and replies...

 

Thanks to Viktor for complaining about just using a boolean for saturation

control. Now changed to accept a predicate that also provides a callback for

arbitrary processing on saturation:

 

      * @param saturate if nonnull, a predicate invoked upon attempts

      * to create more than the maximum total allowed threads.  By

      * default, when a thread is about to block on a join or {@link

      * ManagedBlocker}, but cannot be replaced because the

      * maximumPoolSize would be exceeded, a {@link

      * RejectedExecutionException} is thrown.  But if this predicate

      * returns {@code true}, then no exception is thrown, so the pool

      * continues to operate with fewer than the target number of

      * runnable threads, which might not ensure progress.

      *

 

> On 03/14/2016 10:48 AM, Roger Riggs wrote:

>> Is there any chance I can nudge/encourage you to switch the two arguments

>> for keepAliveTime to a single argument using java.time.Duration?  Though it

>> was not introduced until JDK 8 it is a much nicer packaging of a duration.

>> 

 

As Martin mentioned, the initial main rationale for TimeUnit was to avoid

allocation and GC when dealing with small durations used in timeouts and

timings. When value types appear, we'll definitely want to revisit this.

But for now left alone for uniformity with all other j.u.c APIs.

 

> On 03/14/2016 10:54 AM, Chris Purcell wrote:

>> Wouldn't a builder be appropriate here?

>> 

 

Maybe, but the convention is to use factories for all common cases in

class Executors, leaving only advanced users to deal with plain

constructors in concrete classes. And done here for cowardly uniformity

as well.

 

-Doug

 

 

 

_______________________________________________

Concurrency-interest mailing list

[hidden email]

http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Doug Lea
On 03/15/2016 01:12 PM, Markus KARG wrote:
> Sorry if I chime in or this already was discussed, but I did not follow the
> thread from the beginning: I think it would be great if a work stealing executor
> could be configured for a maximum global queue length, so when adding more work
> it will throw RejectedExecutionException in case the global queue length is
> exceeded but no more workers may be allocated.
>

There is no global queue, so no global length.
But you can layer similar control by invoking
ForkJoinTask.getQueuedTaskCount and checking
per-submitter count before invoking fork, execute, etc.

-Doug






_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Markus KARG

Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“. 😊

 

So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?

 

Thanks

-Markus

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 18:23
An: [hidden email]; [hidden email]
Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor

 

On 03/15/2016 01:12 PM, Markus KARG wrote:

> Sorry if I chime in or this already was discussed, but I did not follow the

> thread from the beginning: I think it would be great if a work stealing executor

> could be configured for a maximum global queue length, so when adding more work

> it will throw RejectedExecutionException in case the global queue length is

> exceeded but no more workers may be allocated.

> 

 

There is no global queue, so no global length.

But you can layer similar control by invoking

ForkJoinTask.getQueuedTaskCount and checking

per-submitter count before invoking fork, execute, etc.

 

-Doug

 

 

 

 

 

 

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Viktor Klang

Ä
On Mar 15, 2016 7:57 PM, "Markus KARG" <[hidden email]> wrote:
>
> Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“. 😊

But there is no such thing. Think about it. :-)

>  
>
> So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?
>
>  
>
> Thanks
>
> -Markus
>
>  
>
> Von: Doug Lea
> Gesendet: Dienstag, 15. März 2016 18:23
> An: Markus KARG; [hidden email]
> Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor
>
>  
>
> On 03/15/2016 01:12 PM, Markus KARG wrote:
>
> > Sorry if I chime in or this already was discussed, but I did not follow the
>
> > thread from the beginning: I think it would be great if a work stealing executor
>
> > could be configured for a maximum global queue length, so when adding more work
>
> > it will throw RejectedExecutionException in case the global queue length is
>
> > exceeded but no more workers may be allocated.
>
> > 
>
>  
>
> There is no global queue, so no global length.
>
> But you can layer similar control by invoking
>
> ForkJoinTask.getQueuedTaskCount and checking
>
> per-submitter count before invoking fork, execute, etc.
>
>  
>
> -Doug
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Chris Purcell
In reply to this post by Doug Lea
Won't it be easier to add more parameters in future without ending up with a random set of constructors, though? This API in particular seems very likely to need refinement in future.

On Tue, 15 Mar 2016, 16:13 Doug Lea, <[hidden email]> wrote:

> On 03/14/2016 10:54 AM, Chris Purcell wrote:
>> Wouldn't a builder be appropriate here?
>>

Maybe, but the convention is to use factories for all common cases in
class Executors, leaving only advanced users to deal with plain
constructors in concrete classes. And done here for cowardly uniformity
as well.

-Doug



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Markus KARG
In reply to this post by Viktor Klang

 

Well… each thread has a queue, so we could sum up the number of task in each. What point do I miss?

 

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 20:18
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

Ä
On Mar 15, 2016 7:57 PM, "Markus KARG" <[hidden email]> wrote:


>
> Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“. 😊

But there is no such thing. Think about it. :-)

>  
>
> So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?
>
>  
>
> Thanks
>
> -Markus
>
>  
>
> Von: Doug Lea
> Gesendet: Dienstag, 15. März 2016 18:23
> An: Markus KARG; [hidden email]
> Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor
>
>  
>
> On 03/15/2016 01:12 PM, Markus KARG wrote:
>
> > Sorry if I chime in or this already was discussed, but I did not follow the
>
> > thread from the beginning: I think it would be great if a work stealing executor
>
> > could be configured for a maximum global queue length, so when adding more work
>
> > it will throw RejectedExecutionException in case the global queue length is
>
> > exceeded but no more workers may be allocated.
>
> > 
>
>  
>
> There is no global queue, so no global length.
>
> But you can layer similar control by invoking
>
> ForkJoinTask.getQueuedTaskCount and checking
>
> per-submitter count before invoking fork, execute, etc.
>
>  
>
> -Doug
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Doug Lea
In reply to this post by Kirk Pepperdine
On 03/14/2016 12:54 PM, [hidden email] wrote:

> A number of us have had discussions with Stuart Marks regarding the usability
> of parallel streams in general compute environments.... At issue is that
> there doesn’t exist any means to have the workload describe the parameters
> under which is should function and have it adapt to changing conditions in
> the runtime.

Thanks to David for addressing this in the course of his helpful reply to Ken
Sipe:

On 03/15/2016 04:47 PM, David Holmes wrote:
>> When the environment lies to the VM about what is available it makes it
>> very hard for the VM to try to adjust.
>>

In other words, we don't have any idea about what to do beyond collecting
experience reports from people trying to cope.

-Doug



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Viktor Klang
In reply to this post by Markus KARG


On Tue, Mar 15, 2016 at 10:12 PM, Markus KARG <[hidden email]> wrote:

 

Well… each thread has a queue, so we could sum up the number of task in each. What point do I miss?


That you can only observe one queue at a time, and unless you pause all consumers and producers, you
'll never be able to get a consistent number unless by chance. (Remembering the old Queuing Theory point that queues spend most of their time either full or empty)
 

 

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 20:18
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

Ä


On Mar 15, 2016 7:57 PM, "Markus KARG" <[hidden email]> wrote:

>
> Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“. 😊

But there is no such thing. Think about it. :-)

>  
>
> So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?
>
>  
>
> Thanks
>
> -Markus
>
>  
>
> Von: Doug Lea
> Gesendet: Dienstag, 15. März 2016 18:23
> An: Markus KARG; [hidden email]
> Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor
>
>  
>
> On 03/15/2016 01:12 PM, Markus KARG wrote:
>
> > Sorry if I chime in or this already was discussed, but I did not follow the
>
> > thread from the beginning: I think it would be great if a work stealing executor
>
> > could be configured for a maximum global queue length, so when adding more work
>
> > it will throw RejectedExecutionException in case the global queue length is
>
> > exceeded but no more workers may be allocated.
>
> > 
>
>  
>
> There is no global queue, so no global length.
>
> But you can layer similar control by invoking
>
> ForkJoinTask.getQueuedTaskCount and checking
>
> per-submitter count before invoking fork, execute, etc.
>
>  
>
> -Doug
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

 



--
Cheers,

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Markus KARG

I don’t want to _monitor_ queues, but my proposal was to _query_ for their current lengths at time of task submission.

 

Von: [hidden email]
Gesendet: Mittwoch, 16. März 2016 13:09
An: [hidden email]
Cc: [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

 

 

On Tue, Mar 15, 2016 at 10:12 PM, Markus KARG <[hidden email]> wrote:

 

Well… each thread has a queue, so we could sum up the number of task in each. What point do I miss?

 

That you can only observe one queue at a time, and unless you pause all consumers and producers, you

'll never be able to get a consistent number unless by chance. (Remembering the old Queuing Theory point that queues spend most of their time either full or empty)

 

 

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 20:18
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

Ä


On Mar 15, 2016 7:57 PM, "Markus KARG" <[hidden email]> wrote:


>
> Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“. 😊

But there is no such thing. Think about it. :-)

>  
>
> So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?
>
>  
>
> Thanks
>
> -Markus
>
>  
>
> Von: Doug Lea
> Gesendet: Dienstag, 15. März 2016 18:23
> An: Markus KARG; [hidden email]
> Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor
>
>  
>
> On 03/15/2016 01:12 PM, Markus KARG wrote:
>
> > Sorry if I chime in or this already was discussed, but I did not follow the
>
> > thread from the beginning: I think it would be great if a work stealing executor
>
> > could be configured for a maximum global queue length, so when adding more work
>
> > it will throw RejectedExecutionException in case the global queue length is
>
> > exceeded but no more workers may be allocated.
>
> > 
>
>  
>
> There is no global queue, so no global length.
>
> But you can layer similar control by invoking
>
> ForkJoinTask.getQueuedTaskCount and checking
>
> per-submitter count before invoking fork, execute, etc.
>
>  
>
> -Doug
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

 


 

--

Cheers,

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Roland Kuhn-2
The point of discussion is that “time of task submission” is not nearly as absolute as you make it sound: even counting a single queue’s elements only gives an estimate of the queue length at some unspecified time in the past, and across CPU cores the situation does not get better. What this boils down to is that formulating an absolute upper bound is not possible without heavy coordination overhead (basically removing scalability), an upper bound would always need to be imprecise—and even then it would have quite some impact on overall performance.

Regards,

Roland

17 mar 2016 kl. 22:08 skrev Markus KARG <[hidden email]>:

I don’t want to _monitor_ queues, but my proposal was to _query_ for their current lengths at time of task submission.
 
Von: [hidden email]
Gesendet: Mittwoch, 16. März 2016 13:09
An: [hidden email]
Cc: [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor
 
 
 
On Tue, Mar 15, 2016 at 10:12 PM, Markus KARG <[hidden email]> wrote:
 
Well… each thread has a queue, so we could sum up the number of task in each. What point do I miss?
 
That you can only observe one queue at a time, and unless you pause all consumers and producers, you
'll never be able to get a consistent number unless by chance. (Remembering the old Queuing Theory point that queues spend most of their time either full or empty)
 
 

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 20:18
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

Ä


On Mar 15, 2016 7:57 PM, "Markus KARG" <[hidden email]> wrote:

>
> Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“. 😊

But there is no such thing. Think about it. :-)

>  
>
> So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?
>
>  
>
> Thanks
>
> -Markus
>
>  
>
> Von: Doug Lea
> Gesendet: Dienstag, 15. März 2016 18:23
> An: Markus KARG; [hidden email]
> Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor
>
>  
>
> On 03/15/2016 01:12 PM, Markus KARG wrote:
>
> > Sorry if I chime in or this already was discussed, but I did not follow the
>
> > thread from the beginning: I think it would be great if a work stealing executor
>
> > could be configured for a maximum global queue length, so when adding more work
>
> > it will throw RejectedExecutionException in case the global queue length is
>
> > exceeded but no more workers may be allocated.
>
> > 
>
>  
>
> There is no global queue, so no global length.
>
> But you can layer similar control by invoking
>
> ForkJoinTask.getQueuedTaskCount and checking
>
> per-submitter count before invoking fork, execute, etc.
>
>  
>
> -Doug
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

 


 
-- 
Cheers,
 
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

--
I'm a physicist: I have a basic working knowledge of the universe and everything it contains!
    - Sheldon Cooper (The Big Bang Theory)


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Markus KARG

I see a strong difference between „impossible“ and „inaccurate“ or „having performance impacts“ actually.

 

Von: [hidden email]
Gesendet: Donnerstag, 17. März 2016 22:32
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

The point of discussion is that “time of task submission” is not nearly as absolute as you make it sound: even counting a single queue’s elements only gives an estimate of the queue length at some unspecified time in the past, and across CPU cores the situation does not get better. What this boils down to is that formulating an absolute upper bound is not possible without heavy coordination overhead (basically removing scalability), an upper bound would always need to be imprecise—and even then it would have quite some impact on overall performance.

 

Regards,

 

Roland

 

17 mar 2016 kl. 22:08 skrev Markus KARG <[hidden email]>:

 

I don’t want to _monitor_ queues, but my proposal was to _query_ for their current lengths at time of task submission.

 

Von: [hidden email]
Gesendet: Mittwoch, 16. März 2016 13:09
An: [hidden email]
Cc: [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

 

 

On Tue, Mar 15, 2016 at 10:12 PM, Markus KARG <[hidden email]> wrote:

 

Well… each thread has a queue, so we could sum up the number of task in each. What point do I miss?

 

That you can only observe one queue at a time, and unless you pause all consumers and producers, you

'll never be able to get a consistent number unless by chance. (Remembering the old Queuing Theory point that queues spend most of their time either full or empty)

 

 

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 20:18
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

Ä


On Mar 15, 2016 7:57 PM, "Markus KARG" <[hidden email]> wrote:


>
> Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“. 😊

But there is no such thing. Think about it. :-)

>  
>
> So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?
>
>  
>
> Thanks
>
> -Markus
>
>  
>
> Von: Doug Lea
> Gesendet: Dienstag, 15. März 2016 18:23
> An: Markus KARG; [hidden email]
> Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor
>
>  
>
> On 03/15/2016 01:12 PM, Markus KARG wrote:
>
> > Sorry if I chime in or this already was discussed, but I did not follow the
>
> > thread from the beginning: I think it would be great if a work stealing executor
>
> > could be configured for a maximum global queue length, so when adding more work
>
> > it will throw RejectedExecutionException in case the global queue length is
>
> > exceeded but no more workers may be allocated.
>
> > 
>
>  
>
> There is no global queue, so no global length.
>
> But you can layer similar control by invoking
>
> ForkJoinTask.getQueuedTaskCount and checking
>
> per-submitter count before invoking fork, execute, etc.
>
>  
>
> -Doug
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

 


 

-- 

Cheers,

 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 

--

I'm a physicist: I have a basic working knowledge of the universe and everything it contains!

    - Sheldon Cooper (The Big Bang Theory)

 

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Roland Kuhn-2
What you neglect in this “argument” is that that depends very much on the boundary conditions: in the context of the ForkJoinPool the global count is not available (so it is impossible). Making it available would completely alter the performance and in particular the scalability characteristics, making the hypothetical result something that is no longer described by the name ForkJoinPool—it would be an entirely different thread pool. Implementing something that scales across CPU sockets requires this precise trade-off, this is inherent to the problem that is being solved.

Regards,

Roland

17 mar 2016 kl. 23:04 skrev Markus KARG <[hidden email]>:

I see a strong difference between „impossible“ and „inaccurate“ or „having performance impacts“ actually.
 
Von: [hidden email]
Gesendet: Donnerstag, 17. März 2016 22:32
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor
 
The point of discussion is that “time of task submission” is not nearly as absolute as you make it sound: even counting a single queue’s elements only gives an estimate of the queue length at some unspecified time in the past, and across CPU cores the situation does not get better. What this boils down to is that formulating an absolute upper bound is not possible without heavy coordination overhead (basically removing scalability), an upper bound would always need to be imprecise—and even then it would have quite some impact on overall performance.
 
Regards,
 
Roland
 
17 mar 2016 kl. 22:08 skrev Markus KARG <[hidden email]>:
 
I don’t want to _monitor_ queues, but my proposal was to _query_ for their current lengths at time of task submission.
 
Von: [hidden email]
Gesendet: Mittwoch, 16. März 2016 13:09
An: [hidden email]
Cc: [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor
 
 
 
On Tue, Mar 15, 2016 at 10:12 PM, Markus KARG <[hidden email]> wrote:
 
Well… each thread has a queue, so we could sum up the number of task in each. What point do I miss?
 
That you can only observe one queue at a time, and unless you pause all consumers and producers, you
'll never be able to get a consistent number unless by chance. (Remembering the old Queuing Theory point that queues spend most of their time either full or empty)
 
 

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 20:18
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

Ä

On Mar 15, 2016 7:57 PM, "Markus KARG" <[hidden email]> wrote:

>
> Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“. 😊
But there is no such thing. Think about it. :-)
>  
>
> So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?
>
>  
>
> Thanks
>
> -Markus
>
>  
>
> Von: Doug Lea
> Gesendet: Dienstag, 15. März 2016 18:23
> An: Markus KARG; [hidden email]
> Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor
>
>  
>
> On 03/15/2016 01:12 PM, Markus KARG wrote:
>
> > Sorry if I chime in or this already was discussed, but I did not follow the
>
> > thread from the beginning: I think it would be great if a work stealing executor
>
> > could be configured for a maximum global queue length, so when adding more work
>
> > it will throw RejectedExecutionException in case the global queue length is
>
> > exceeded but no more workers may be allocated.
>
> > 
>
>  
>
> There is no global queue, so no global length.
>
> But you can layer similar control by invoking
>
> ForkJoinTask.getQueuedTaskCount and checking
>
> per-submitter count before invoking fork, execute, etc.
>
>  
>
> -Doug
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
 

 
-- 
Cheers,
 
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
 
--
I'm a physicist: I have a basic working knowledge of the universe and everything it contains!
    - Sheldon Cooper (The Big Bang Theory)

--
I'm a physicist: I have a basic working knowledge of the universe and everything it contains!
    - Sheldon Cooper (The Big Bang Theory)


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

Viktor Klang
In reply to this post by Markus KARG

I didn't say anything about monitoring.

--
Cheers,

On Mar 17, 2016 10:08 PM, "Markus KARG" <[hidden email]> wrote:

I don’t want to _monitor_ queues, but my proposal was to _query_ for their current lengths at time of task submission.

 

Von: [hidden email]
Gesendet: Mittwoch, 16. März 2016 13:09
An: [hidden email]
Cc: [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

 

 

On Tue, Mar 15, 2016 at 10:12 PM, Markus KARG <[hidden email]> wrote:

 

Well… each thread has a queue, so we could sum up the number of task in each. What point do I miss?

 

That you can only observe one queue at a time, and unless you pause all consumers and producers, you

'll never be able to get a consistent number unless by chance. (Remembering the old Queuing Theory point that queues spend most of their time either full or empty)

 

 

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 20:18
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

Ä


On Mar 15, 2016 7:57 PM, "Markus KARG" <[hidden email]> wrote:


>
> Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“. 😊

But there is no such thing. Think about it. :-)

>  
>
> So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?
>
>  
>
> Thanks
>
> -Markus
>
>  
>
> Von: Doug Lea
> Gesendet: Dienstag, 15. März 2016 18:23
> An: Markus KARG; [hidden email]
> Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor
>
>  
>
> On 03/15/2016 01:12 PM, Markus KARG wrote:
>
> > Sorry if I chime in or this already was discussed, but I did not follow the
>
> > thread from the beginning: I think it would be great if a work stealing executor
>
> > could be configured for a maximum global queue length, so when adding more work
>
> > it will throw RejectedExecutionException in case the global queue length is
>
> > exceeded but no more workers may be allocated.
>
> > 
>
>  
>
> There is no global queue, so no global length.
>
> But you can layer similar control by invoking
>
> ForkJoinTask.getQueuedTaskCount and checking
>
> per-submitter count before invoking fork, execute, etc.
>
>  
>
> -Doug
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

 


 

--

Cheers,

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Customized ForkJoinPool constructor

William Louth
Wouldn't it not be better to simply allow the means to collect such data, via some form of interception/callback API, if needed by a particular extension rather than forcing the implementation to meet such requirements irrespective of the degree of fulfillment of such.

On 18/03/2016 09:30, Viktor Klang wrote:

I didn't say anything about monitoring.

--
Cheers,

On Mar 17, 2016 10:08 PM, "Markus KARG" <[hidden email]> wrote:

I don’t want to _monitor_ queues, but my proposal was to _query_ for their current lengths at time of task submission.

 

Von: [hidden email]
Gesendet: Mittwoch, 16. März 2016 13:09
An: [hidden email]
Cc: [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

 

 

On Tue, Mar 15, 2016 at 10:12 PM, Markus KARG <[hidden email]> wrote:

 

Well… each thread has a queue, so we could sum up the number of task in each. What point do I miss?

 

That you can only observe one queue at a time, and unless you pause all consumers and producers, you

'll never be able to get a consistent number unless by chance. (Remembering the old Queuing Theory point that queues spend most of their time either full or empty)

 

 

 

Von: [hidden email]
Gesendet: Dienstag, 15. März 2016 20:18
An: [hidden email]
Cc: [hidden email]; [hidden email]
Betreff: Re: [concurrency-interest] Customized ForkJoinPool constructor

 

Ä


On Mar 15, 2016 7:57 PM, "Markus KARG" <[hidden email]> wrote:
>
> Doug, with „global Queue length“ I did not mean „length of the global Queue“ but „sum of lenghts of all queues“.
😊

But there is no such thing. Think about it. :-)

>  
>
> So do you propose to _wrap_ the Executor by the application programmer, or  is this a use case for the discussed Predicate?
>
>  
>
> Thanks
>
> -Markus
>
>  
>
> Von: Doug Lea
> Gesendet: Dienstag, 15. März 2016 18:23
> An: Markus KARG; [hidden email]
> Betreff: Re: AW: [concurrency-interest] Customized ForkJoinPool constructor
>
>  
>
> On 03/15/2016 01:12 PM, Markus KARG wrote:
>
> > Sorry if I chime in or this already was discussed, but I did not follow the
>
> > thread from the beginning: I think it would be great if a work stealing executor
>
> > could be configured for a maximum global queue length, so when adding more work
>
> > it will throw RejectedExecutionException in case the global queue length is
>
> > exceeded but no more workers may be allocated.
>
> > 
>
>  
>
> There is no global queue, so no global length.
>
> But you can layer similar control by invoking
>
> ForkJoinTask.getQueuedTaskCount and checking
>
> per-submitter count before invoking fork, execute, etc.
>
>  
>
> -Doug
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>  
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

 



 

--

Cheers,

 



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
12