DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Mastering Concurrency: An In-Depth Guide to Java's ExecutorService
  • Testing the Untestable and Other Anti-Patterns
  • How To Create Asynchronous and Retryable Methods With Failover Support
  • All About GPU Threads, Warps, and Wavefronts

Trending

  • DZone's Article Submission Guidelines
  • A Complete Guide to Modern AI Developer Tools
  • Start Coding With Google Cloud Workstations
  • Is Agile Right for Every Project? When To Use It and When To Avoid It
  1. DZone
  2. Data Engineering
  3. Data
  4. JDK9's ForkJoinPool Upgrades

JDK9's ForkJoinPool Upgrades

Java 9 snuck in some small but important changes to the ForkJoinPool. Let's take a closer look.

By 
Grzegorz Piwowarek user avatar
Grzegorz Piwowarek
·
Jul. 17, 18 · News
Likes (9)
Comment
Save
Tweet
Share
13.8K Views

Join the DZone community and get the full member experience.

Join For Free

while everyone's been busy with modularity, local-variable-type-inference, and other "next big things" from recent jdk releases, there's a fairly small but important update for the forkjoinpool that deserves some attention.

forkjoinpool was an experiment brought to life by jdk 7 that attracted a lot of attention. its main selling point was the implementation of the idea of work-stealing. simply put, free threads were able to steal tasks from worker queues of other busy threads within the same pool.

forkjoinpool configuration

since the beginning, forkjoinpool suffered from a lack of reasonable config options. the most generous constructor offered us only parameters such as:

  1. parallelism level
  2. a custom forkjoinworkerthreadfactory
  3. a custom uncaughtexceptionhandler
public forkjoinpool(
int parallelism,
forkjoinworkerthreadfactory factory,
uncaughtexceptionhandler handler,
boolean asyncmode)

for some of you, that was a bit more intrusive. you would discover that there's one more private constructor available since jdk 8, which offers an additional, very useful parameter — the worker name prefix.

i must admit that it was very disappointing to see this one being private and not accessible using any legal means, but, luckily, there are other ways for achieving the same result.

jdk9

jdk9 brought huge improvements firstly, the implementation was rewritten using varhandles, and we got a new, very generous constructor exposing additional configuration parameters such as:

public forkjoinpool(
// ...
int corepoolsize,
int maximumpoolsize,
int minimumrunnable,
predicate<? super forkjoinpool> saturate,
long keepalivetime, timeunit unit
)

let's see what do those give us.

int corepoolsize

this one is pretty self-explanatory; the int corepoolsize is the number of threads to keep in the pool. 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. however, it'd be important to add that the maximum possible value is 32767.

int maximumpoolsize

the int maximumpoolsize is pretty self-explanatory, as well. by default, 256 spare threads are allowed.

int minimumrunnable

this is the first huge improvement that gives us an opportunity to ensure that there's at least n usable threads in the pool. usable threads are those that aren't blocked by a join() or a managedblocker instance. when a number of free unblocked threads go below the provided value, new threads get spawned if the maximumpoolsize allows it.

setting the minimumrunnable to a larger value might ensure better throughput in the presence of blocking tasks for the cost of the increased overhead (remember to make sure that gains are bigger than costs).

if we know that our tasks won't need any additional threads, we can go for 0.

predicate<? super forkjoinpool> saturate

if we end up in a situation when there's an attempt made to spawn more threads in order to satisfy the minimumrunnable constraint, but it gets blocked by the maximumpoolsize , by default, rejectedexecutionexception("thread limit exceeded replacing blocked worker") is thrown.

but now, we can provide a predicate that gets fired once such situation occurs and, eventually, allow thread pool saturation by ignoring the minimumrunnable value.

it's good to see that we have a choice now.

long keepalivetime, timeunit unit

just like with the classic executorservice , we can now specify how long unused threads should be kept alive before getting terminated.

keep in mind that it applies only for threads spawned above the corepoolsize value.

conclusion

jdk9 brought huge improvements for forkjoinpool .

unfortunately, we still can't provide a custom worker name prefix easily and cap the size of the worker queue, which is now capped at "1 << 24." this is way too much for any reasonable value.

if you're interested in seeing the raw diff, you can find it here .

Data Types Task (computing) Thread pool Overhead (computing) Implementation Diff Blocks Release (computing) IT Modularity (networks)

Published at DZone with permission of Grzegorz Piwowarek, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Mastering Concurrency: An In-Depth Guide to Java's ExecutorService
  • Testing the Untestable and Other Anti-Patterns
  • How To Create Asynchronous and Retryable Methods With Failover Support
  • All About GPU Threads, Warps, and Wavefronts

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: