Modern Concurrency in Java (A N M Bazlur Rahman) (Z-Library)
Author: A N M Bazlur Rahman
技术
Welcome to the future of Java. With this book, you'll explore the transformative world of Java 21's key feature: virtual threads. Remember struggling with the cost of thread creation, encountering limitations on scalability, and facing difficulties in achieving high throughput? Those days are over. This practical guide takes you from Java 1.0 to the cutting-edge advancements of Project Loom.
📄 File Format:
PDF
💾 File Size:
4.5 MB
26
Views
0
Downloads
0.00
Total Donations
📄 Text Preview (First 20 pages)
ℹ️
Registered users can read the full content for free
Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.
📄 Page
1
(This page has no text content)
📄 Page
2
Modern Concurrency in Java Virtual Threads, Structured Concurrency, and Beyond A N M Bazlur Rahman
📄 Page
3
Modern Concurrency in Java by A N M Bazlur Rahman Copyright © 2025 A N M Bazlur Rahman. All rights reserved. Published by O’Reilly Media, Inc., 141 Stony Circle, Suite 195, Santa Rosa, CA 95401. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (https://oreilly.com). For more information, contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com. Acquisitions Editor: Louise Corrigan Development Editor: Angela Rufino Production Editor: Jonathon Owen Copyeditor: Audrey Doyle Proofreader: Miah Sandvik Indexer: nSight, Inc. Cover Designer: Karen Montgomery Cover Illustrator: José Marzan Jr. Interior Designer: David Futato Interior Illustrator: Kate Dullea September 2025: First Edition Revision History for the First Edition
📄 Page
4
2025-09-16: First Release See https://oreilly.com/catalog/errata.csp?isbn=9781098165413 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Modern Concurrency in Java, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc. The views expressed in this work are those of the author and do not represent the publisher’s views. While the publisher and the author have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the author disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights. 978-1-098-16541-3 [LSI]
📄 Page
5
Dedication To my daughter, Rushda, whose love, growth, and boundless curiosity inspired the pages of this book. The sound of your laughter and your playful interruptions motivated every word I wrote. To my beloved wife, Tabassum, for your unwavering support and for creating the loving space that allowed me to complete this journey.
📄 Page
6
Preface Why I Wrote This Book Concurrency has long been one of the most challenging aspects of Java development. It has consistently evolved to meet the demands of modern software development while maintaining a strong commitment to backward compatibility. Among all the advancements Java has introduced over the years, Project Loom’s introduction of virtual threads marks a fundamental shift in the world of concurrency. Concurrency is inherently challenging, and this difficulty has only increased with the rise in performance demands. Even for seasoned developers, managing it effectively remains a complex task. Today, modern applications are primarily I/O-driven, as they interact with numerous other systems, especially within the microservices architecture that dominates recent software development to meet the growing demands of scalability. I/O operations often take a significant amount of time. When a thread makes an I/O call, it typically has to wait for the operation to complete, which has been the traditional approach. While modern operating systems can manage millions of open sockets, the number of available threads remains limited. As a result, meeting the growing demand for higher throughput with traditional threads has become increasingly complex. In response to this limitation, various techniques and alternative concurrency models have been devised, but each comes with its own set of trade-offs. Virtual threads represent a promising solution by leveraging lightweight, user-mode threads that can be multiplexed onto a smaller number of kernel threads. This approach enables more efficient use of system resources. It enhances scalability, marking a notable improvement in the world of concurrency.
📄 Page
7
When I first encountered virtual threads, I was immediately intrigued. They felt like a long-awaited breakthrough that could fundamentally change how we write concurrent programs on the JVM, offering a simple and elegant solution where Java previously lacked one. I began experimenting with virtual threads, documenting my findings on my blog, and speaking at conferences. The enthusiastic response from the developer community reaffirmed that virtual threads were not just another enhancement but a fundamental shift in the approach to concurrency. As I continued to explore, I discovered a wealth of resources emerging around virtual threads—official documentation, insightful blog posts, GitHub repositories with real-world examples, and excellent conference sessions. While these resources were individually valuable, each focused on different aspects of the topic. Some addressed technical implementations, while others discussed migration strategies and specific use cases. Through continuous writing, speaking, and hands-on work, I gained a clearer and more comprehensive understanding of the subject. This exploration provided a comprehensive understanding of the motivations behind project Loom, its integration with Java’s existing concurrency model, and its implications for building scalable and maintainable systems. My respect for Java’s ability to adapt to change while maintaining backward compatibility has only intensified throughout this journey. Eventually, I realized there was an opportunity to consolidate all this understanding into a single, practical resource. This book is not just a theoretical exploration but a practical, hands-on guide that gathers all the necessary concepts, examples, and best practices into a single, comprehensive resource.
📄 Page
8
Who This Book Is For This book is designed for Java developers who already possess a foundational understanding of concurrency and multithreading. It is not a beginner’s guide to these topics. Instead, it targets those who have experience writing concurrent programs using traditional tools, such as Thread, ExecutorService, synchronization, and collection utilities like ReentrantLock and Semaphore, and are looking to deepen their understanding of the modern concurrency features introduced in recent Java releases, particularly virtual threads, structured concurrency, and scoped values. If you’re looking to learn the fundamentals of concurrency, Java Concurrency in Practice by Brian Goetz (Addison-Wesley Professional) is still the recommended book. If you’ve ever encountered challenges with thread exhaustion, blocking I/O, thread pool tuning, or managing complex lifecycle and cancellation logic, this book will help you rethink these issues in light of Java’s evolving concurrency model. It is particularly beneficial for: Mid- to senior-level developers aiming to modernize their concurrent code Architects designing scalable systems Performance-oriented engineers interested in building robust concurrent applications Team leads assessing new technologies Anyone curious about the future of Java concurrency Junior developers with a basic understanding of Java will also find this book useful for an overview of modern concurrency. However, a prior or concurrent study of foundational topics such as synchronization, race conditions, and data publishing is highly recommended for a complete understanding. These fundamentals are vital for effectively writing concurrent code in your applications. While some modern frameworks hide these details from everyday developers, things become critical when
📄 Page
9
encountering a serious bug. Fundamental knowledge is always essential for understanding the subject, and concurrency is no exception.
📄 Page
10
What This Book Offers This book consolidates everything I’ve learned about Project Loom and virtual threads into one comprehensive resource. Inside, you will find: An exploration of Java’s concurrency evolution, from platform threads and the Executor framework to CompletableFuture and reactive programming A deep dive into the mechanics of virtual threads, structured concurrency, and scoped values Practical, real-world examples that demonstrate how to apply these new features effectively Extensive coverage of not only virtual threads but also structured concurrency and scoped values Guidance on how modern frameworks like Spring Boot, Quarkus, and Jakarta EE are integrating virtual threads Whether you are new to virtual threads or have been following Project Loom from its inception, you will discover valuable insights and practical knowledge. The examples and concepts in this book require at least JDK 21, as that is when virtual threads became officially available. However, some chapters discuss features that are still in preview or have been recently finalized. Therefore, having access to a newer JDK version, such as 24 or even 25, will enable you to make the most of all the examples and discussions.
📄 Page
11
How This Book Is Organized This book is structured to take you on a journey from understanding the importance of virtual threads to mastering their use in production applications. Here’s what you can expect in each chapter: Chapter 1, “Introduction” We begin by exploring the evolution of concurrency in Java, tracing its development from platform threads through the Executor framework, Fork/Join, and CompletableFuture, with a brief introduction to reactive programming. This historical context helps you appreciate why virtual threads are a game changer. You’ll discover the trade-offs we’ve made over the years and understand why Project Loom takes a fundamentally different approach. Chapter 2, “Understanding Virtual Threads” In this chapter, we introduce virtual threads in a hands-on manner. You’ll learn what they are, how they differ from platform threads, and how to create them. We explore throughput improvements, scalability benefits, and practical examples. Key topics include rate limiting with Semaphores and important limitations such as pinning and ThreadLocal considerations. Chapter 3, “The Mechanics of Modern Concurrency in Java” This chapter dives deep into the mechanics of concurrency. We investigate thread pools, the Executor framework, and the ForkJoinPool that powers virtual threads. A key highlight is building our own virtual thread implementation from scratch using continuations. By creating NanoThreads, you’ll gain a profound understanding of how virtual threads operate under the hood.
📄 Page
12
Chapter 4, “Structured Concurrency” Here, we discuss one of Project Loom’s most significant innovations: StructuredTaskScope. You’ll learn how it addresses the problems of unstructured concurrency, master different joining policies, handle exceptions gracefully, and build robust concurrent applications. The chapter covers everything from basic usage to custom joiners and nested scopes. Please note that at the time of writing, structured concurrency is still in preview. I hope this preview version remains largely unchanged, but if there are updates, I will address them in subsequent editions. Chapter 5, “Scoped Values” Context propagation in highly concurrent applications has always posed challenges. This chapter demonstrates how scoped values provide a superior alternative to ThreadLocal for virtual threads. You’ll learn the API, see practical examples in the context of structured concurrency, and understand when and how to transition from ThreadLocal. Chapter 6, “The Relevance of Reactive Java in Light of Virtual Threads” In this chapter, we aim to understand the differences in approaching concurrency between virtual threads and reactive programming. We examine the differences between blocking and nonblocking I/O, event-driven architecture, and the trade-offs associated with each approach. This chapter will help you make informed choices about when to utilize virtual threads versus reactive frameworks. Chapter 7, “Modern Frameworks Utilizing Virtual Threads” Explore how major frameworks are embracing virtual threads. We cover Spring Boot, Quarkus, and Jakarta EE, providing practical configuration examples and best
📄 Page
13
practices. This chapter bridges the gap between learning about virtual threads and applying them in production environments. Chapter 8, “Conclusion and Takeaways” We conclude with key insights and a look at the future of concurrent programming in Java. How to Read This Book This book is designed to be read sequentially, as each chapter builds on concepts from the previous ones. However, if you are already familiar with certain topics, feel free to jump ahead to the chapters that interest you the most. For beginners to virtual threads Start with Chapter 1 to understand the historical context, then proceed through each chapter in order. For experienced developers If you prefer, you may skim Chapter 1 and proceed directly to Chapter 2 for hands-on experience with virtual threads. Don’t skip Chapter 3; building virtual threads from scratch provides invaluable insights. For architects and team leads Pay special attention to Chapters 4–5, which cover structured concurrency and scoped values, as well as Chapter 6, which compares these concepts with reactive programming. This will aid in making informed architectural decisions.
📄 Page
14
A Hands-On Approach Each chapter includes plenty of code examples, and I expect that as you read, you’ll have your IDE open to try out the code examples one by one. Don’t just read the code; run it, modify it, break it, and fix it. There’s no better way to internalize these concepts than through experimentation. For your convenience, all source code is available at https://github.com/Modern-Concurrency-in-Java. Each chapter comes with its own package containing fully runnable examples. I strongly encourage you to write the code yourself while reading the book. However, if you prefer to skim and experiment with the code, feel free to clone the repository before you begin reading. If you have a technical question or a problem using the code examples, please send an email to support@oreilly.com. This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission. We appreciate, but generally do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “Modern Concurrency in Java by A N M Bazlur Rahman (O’Reilly). Copyright 2025 A N M Bazlur Rahman, 978-1-098-16541-3.” If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at permissions@oreilly.com.
📄 Page
15
Conventions Used in This Book The following typographical conventions are used in this book: Italic Indicates new terms, URLs, email addresses, filenames, and file extensions. Constant width Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, databases, data types, environment variables, statements, and keywords. Constant width bold Shows commands or other text that should be typed literally by the user. Constant width italic Shows text that should be replaced with user-supplied values or by values determined by context. TIP This element signifies a tip or suggestion. NOTE This element signifies a general note.
📄 Page
16
WARNING This element indicates a warning or caution. O’Reilly Online Learning NOTE For more than 40 years, O’Reilly Media has provided technology and business training, knowledge, and insight to help companies succeed. Our unique network of experts and innovators share their knowledge and expertise through books, articles, and our online learning platform. O’Reilly’s online learning platform gives you on-demand access to live training courses, in-depth learning paths, interactive coding environments, and a vast collection of text and video from O’Reilly and 200+ other publishers. For more information, visit https://oreilly.com. How to Contact Us Please address comments and questions concerning this book to the publisher: O’Reilly Media, Inc. 141 Stony Circle, Suite 195 Santa Rosa, CA 95401 800-889-8969 (in the United States or Canada) 707-827-7019 (international or local)
📄 Page
17
707-829-0104 (fax) support@oreilly.com https://oreilly.com/about/contact.html We have a web page for this book, where we list errata and any additional information. You can access this page at https://oreil.ly/modern- concurrency-java. For news and information about our books and courses, visit https://oreilly.com. Find us on LinkedIn: https://linkedin.com/company/oreilly-media Watch us on YouTube: https://youtube.com/oreillymedia Acknowledgments First and foremost, I am deeply grateful to Allah (glory be to Him, the Exalted) for granting me the strength, patience, and opportunity to complete this book. Without His help, this journey would not have been possible. I extend my heartfelt thanks to my wife and daughter, who made the greatest sacrifice by allowing me the time to write, time we could have spent together. Their support, patience, and love carried me through the many long nights and weekends dedicated to this project. This book is as much theirs as it is mine, and I am deeply grateful for their understanding and unwavering support. I would also like to thank my parents, whose pride in my work continues to inspire me. Witnessing their joy with each book I write is one of my greatest rewards and motivates me to continue pushing the boundaries of my writing. Additionally, I am grateful to my father-in-law and mother-in- law for their enthusiasm and encouragement regarding my work. Their warm support and genuine excitement are absolutely invaluable to me.
📄 Page
18
I would like to express my appreciation to the reviewers, editors, and the entire production team at O’Reilly. Thank you for your trust and tireless efforts in shaping this book. To the Java community, your ideas, discussions, and contributions surrounding Project Loom and modern concurrency have been invaluable. Your role in helping me write a book that is both practical and forward-looking cannot be overstated. Finally, to you, the reader: thank you for taking the time to pick up this book. I hope it empowers you to write better, safer, and more modern concurrent Java code. I look forward to hearing about your experiences with the book and its impact on your work.
📄 Page
19
Chapter 1. Introduction Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once. —Rob Pike To truly appreciate something, it is crucial to know how it came to be, especially if we can discern the steps taken and the challenges overcome along the way. This understanding not only highlights ongoing progress but also helps us understand its relevance. Similarly, Java concurrency has come a long way since its inception. It took a long time to evolve to its current state. But if we want to understand recent advancements, such as virtual threads and structured concurrency in modern Java, we must first delve into its evolution. In this chapter, we will give you an initial view of Java concurrency and then briefly discuss how it has developed over time. A Brief History of Threads in Java Java was designed with concurrency in mind; it was one of the first languages to provide built-in support for multithreading. Over the years, Java’s concurrency capabilities have been improved and refined, leaving behind some potholes and lessons along the way. Java concurrency began with basic synchronization and thread management. Then came the introduction of the java.util.concurrent package in Java 5, which brought important new capabilities such as the Executor framework, locks, and concurrent collections. Next, with the introduction of the Fork/Join framework in Java 7, Java engaged the concurrency performance of multicore processors. And most recently, with Project Loom, Java addressed the complexity and limitations of traditional thread-based concurrency, with lightweight, user-mode threads and
📄 Page
20
structured concurrency, ultimately aiming to make concurrent development simpler and more efficient. Why does this evolution matter so much? As we uncover how Java’s concurrency story unfolds, we discover a relentless pursuit of greater efficiency and simplified programming in the face of ever-growing complexity. This narrative extends beyond just Java; it reflects the trajectory of software development and Java’s continued aspirations. Let’s dive deeper into understanding this evolution and appreciate the strides made in Java concurrency. Java Is Made of Threads Concurrency was an explicit design goal of Java, a language that was released with built-in thread capability and a threading feature that was a key differentiator of the language. It removed developers’ dependency on operating-system-specific features to achieve concurrency. In Java, a thread is the smallest unit of execution. It is an independent path of execution running within a program. Threads share the same address space, meaning they have access to the same variables and data structures of the program. However, each thread maintains its own program counter, stack, and local variables, enabling it to operate independently. This design also facilitates interaction among threads when necessary. However, Java’s threading model relies on the underlying operating system to schedule and execute threads. The operating system allocates CPU time to each thread, managing the transition between threads to ensure efficient execution. By distributing threads across multiple CPUs, the system can achieve true parallelism, enhancing the performance of concurrent applications (Figure 1-1).
The above is a preview of the first 20 pages. Register to read the complete e-book.