In continuation to previous post https://bit.ly/4bsoGg0 Once you get basics of Reactive programming, it becomes more interesting as we delve into further details. Let's talk about further components which come from libraries like Project Reactor. There are something called Mono and Flux. Both are different types of Publishers supported in reactive programming. Understanding these is as simple as reading a line of code. With the concept of Mono and Flux, you deal with a stream of data and not just the static data itself. Lets break it with an example. When we are fetching a unique user from a database based on id, we use Mono. Mono deals with fetching at most one object (0 or 1) or an error. Flux can be used to fetch 0 to N number of items, like a list of active users from a database. Instead of going into more details and confusing you, let's talk about other buzz words we use in reactive programming. Operators: In reactive programming, we don't just "get" data. We transform it as it flows. There are different operators which can be used for transformation without those for-loops which we were bound to use in imperative Java. Map: For synchronous transformation, like changing the type of a variable on the fly. FlatMap: Used for asynchronous transformations, like performing a database call for every item in a Flux. Filter: Filter out only the data which meets a given criteria. Concept of Backpressure: A very critical concept which should be carefully used in reactive programming; otherwise, the situation could go worse than imperative programming. Backpressure is a concept where the consumer can send a signal to the producer like "Hey, slow down, I can only handle five items at a time right now." In this way, the system maintains its own balance and eventual crashing of an application can be prevented. A Simple Example: Look at the logic below. In older Java, you'd wait for the whole list. In Reactive, you handle it as it comes. The stream starts, filters out the "C++" hurdle, transforms the rest, and then finally prints them. No curly brace hurdles, no complex declarations. Trust me, once you start thinking in streams, going back to the old way feels like taking a step backward. It might take extra time to master the operators, but the ultimate satisfaction of building a non-blocking, resilient system is worth the effort.
Reactive Programming with Mono and Flux Explained
More Relevant Posts
-
In continuation to previous post https://lnkd.in/ggua79hw I’m damn sure that once you’ve crossed the initial hurdle of understanding Mono and Flux, you’ll run straight into the next problem: how do you actually migrate your existing code without making a mess? Most beginners make a classic mistake. They take a traditional method and just use a Mono.just() on it. Yeah, you guessed it right—it’s a bad move. Why not Mono.just()? Trust me, Mono.just() evaluates the value immediately. If you’ve got a heavy database call inside there, it runs before the stream even starts. You end up with the same performance hurdles we had in imperative Java. Using fromCallable and fromRunnable: In the reactive world, we have better ways to handle the logic you’ve already written: fromCallable: This is for when your method actually returns something. It ensures the code inside only runs when someone subscribes. It also handles those annoying checked exception hurdles without you needing extra try-catch blocks. fromRunnable: Use this for tasks that don't return data—like sending a signal or logging. It finishes the Mono as soon as the task is done. The key is to use these tools to bridge the gap. It keeps the system balanced and responsive, which is what we’re all aiming for. There is also something called defer, which is basically the ultimate way to keep your data fresh. I won't dive into it now as it deserves its own space, but trust me, it’s a game-changer. We’ll break it down with some real-world examples in the next post.
Senior Software Engineer | Distributed Systems | Kafka | 7M+ Events/Day | Java, Python | AI Agents (GPT)
In continuation to previous post https://bit.ly/4bsoGg0 Once you get basics of Reactive programming, it becomes more interesting as we delve into further details. Let's talk about further components which come from libraries like Project Reactor. There are something called Mono and Flux. Both are different types of Publishers supported in reactive programming. Understanding these is as simple as reading a line of code. With the concept of Mono and Flux, you deal with a stream of data and not just the static data itself. Lets break it with an example. When we are fetching a unique user from a database based on id, we use Mono. Mono deals with fetching at most one object (0 or 1) or an error. Flux can be used to fetch 0 to N number of items, like a list of active users from a database. Instead of going into more details and confusing you, let's talk about other buzz words we use in reactive programming. Operators: In reactive programming, we don't just "get" data. We transform it as it flows. There are different operators which can be used for transformation without those for-loops which we were bound to use in imperative Java. Map: For synchronous transformation, like changing the type of a variable on the fly. FlatMap: Used for asynchronous transformations, like performing a database call for every item in a Flux. Filter: Filter out only the data which meets a given criteria. Concept of Backpressure: A very critical concept which should be carefully used in reactive programming; otherwise, the situation could go worse than imperative programming. Backpressure is a concept where the consumer can send a signal to the producer like "Hey, slow down, I can only handle five items at a time right now." In this way, the system maintains its own balance and eventual crashing of an application can be prevented. A Simple Example: Look at the logic below. In older Java, you'd wait for the whole list. In Reactive, you handle it as it comes. The stream starts, filters out the "C++" hurdle, transforms the rest, and then finally prints them. No curly brace hurdles, no complex declarations. Trust me, once you start thinking in streams, going back to the old way feels like taking a step backward. It might take extra time to master the operators, but the ultimate satisfaction of building a non-blocking, resilient system is worth the effort.
To view or add a comment, sign in
-
-
In continuation to previous post: https://lnkd.in/gyASSi7Q We have been talking till now about theories around fromCallable and fromRunnable. Question comes: how to use one and when to use one. In this post I would cover fromCallable. By using fromCallable, you direct the system “Don’t call this until someone asks for”. You heard this right. It is as simple as that. Let’s take an example of fetching user data from database. In imperative coding in Java, database would get hit immediately even if it is not required by that time. Seeing the two side-by-side is the only way to really understand the prowess of the reactive approach. It’s all about getting rid of those blocking hurdles. In the reactive world, the thread is free to handle other tasks while the data is being fetched. Look at this code. The thread sits idle while fetchUser does its thing. public User getAndProcessUser(String id) { // Thread stops here and waits... User user = service.fetchUser(id); user.setName(user.getName().toUpperCase()); return user; } Now, look at the reactive version. We wrap the call and transform the data as a stream. public Mono<User> getAndProcessUserReactive(String id) { return Mono.fromCallable(() -> service.fetchUser(id)) .map(user -> { user.setName(user.getName().toUpperCase()); return user; }); } In the first example, if the database takes 2 seconds, your thread is dead for 2 seconds. In the second example, using fromCallable, the system only executes the call when a subscriber is ready, and it doesn't hold the thread hostage while waiting. Once you start scaling to thousands of users, this is the difference between a system that stays balanced and one that just crashes. We’ll talk about defer and how to handle more complex "fresh data" scenarios in the next post.
Senior Software Engineer | Distributed Systems | Kafka | 7M+ Events/Day | Java, Python | AI Agents (GPT)
In continuation to previous post https://bit.ly/4bsoGg0 Once you get basics of Reactive programming, it becomes more interesting as we delve into further details. Let's talk about further components which come from libraries like Project Reactor. There are something called Mono and Flux. Both are different types of Publishers supported in reactive programming. Understanding these is as simple as reading a line of code. With the concept of Mono and Flux, you deal with a stream of data and not just the static data itself. Lets break it with an example. When we are fetching a unique user from a database based on id, we use Mono. Mono deals with fetching at most one object (0 or 1) or an error. Flux can be used to fetch 0 to N number of items, like a list of active users from a database. Instead of going into more details and confusing you, let's talk about other buzz words we use in reactive programming. Operators: In reactive programming, we don't just "get" data. We transform it as it flows. There are different operators which can be used for transformation without those for-loops which we were bound to use in imperative Java. Map: For synchronous transformation, like changing the type of a variable on the fly. FlatMap: Used for asynchronous transformations, like performing a database call for every item in a Flux. Filter: Filter out only the data which meets a given criteria. Concept of Backpressure: A very critical concept which should be carefully used in reactive programming; otherwise, the situation could go worse than imperative programming. Backpressure is a concept where the consumer can send a signal to the producer like "Hey, slow down, I can only handle five items at a time right now." In this way, the system maintains its own balance and eventual crashing of an application can be prevented. A Simple Example: Look at the logic below. In older Java, you'd wait for the whole list. In Reactive, you handle it as it comes. The stream starts, filters out the "C++" hurdle, transforms the rest, and then finally prints them. No curly brace hurdles, no complex declarations. Trust me, once you start thinking in streams, going back to the old way feels like taking a step backward. It might take extra time to master the operators, but the ultimate satisfaction of building a non-blocking, resilient system is worth the effort.
To view or add a comment, sign in
-
-
In continuation to previous post https://lnkd.in/gh-53USP Once you have a grip on Mono, Flux, and the basic operators, it’s time to talk about what actually makes the engine run under the hood. In reactive programming, we have something called Schedulers. The key thing to understand here is that by default, reactive code is not necessarily multi-threaded. It runs on whatever thread starts the subscription. But to get the real prowess out of your system, you need to decide which "worker" handles which task. In libraries like Project Reactor, we use operators like subscribeOn and publishOn to switch the context. When we talk about Schedulers, the first question that pops up is whether the whole thing is multi-threaded or not. I'm damn sure many people get confused here thinking Reactive means Multi-threaded by default. Yeah, you read it right—it isn’t. Unless you specify a Scheduler, the code just runs on the current thread. But the real prowess of Reactive programming comes when you start using these Schedulers to distribute the load across multiple threads. Let's look at the logic of which ones actually bring multi-threading to the table: • Schedulers.immediate(): No multi-threading here. It stays on the same thread. It’s as simple as that. • Schedulers.single(): This one is technically a separate thread, but it’s just one worker for everyone. So, it's not "multi-threaded" in the sense of parallel execution; it’s just offloading work to a single background worker. • Schedulers.parallel(): This is where true multi-threading happens. It creates a pool of threads based on your CPU cores. If you have 8 cores, it can run 8 tasks at the same time. It’s perfect for CPU-heavy logic where you want to squeeze every bit of performance out of your machine. • Schedulers.boundedElastic(): This is also multi-threaded. It creates a pool of threads that grows and shrinks based on the need. It's the best choice when you're dealing with "delves" like slow database calls or API hits, as it ensures one slow task doesn't block the whole system. Example: Flux.just("User1", "User2") .subscribeOn(Schedulers.boundedElastic()) // Start here for I/O .map(name -> name.toUpperCase()) .publishOn(Schedulers.parallel()) // Switch to parallel for heavy processing .subscribe(System.out::println); The key thing to understand here is that you are the one in control. By choosing parallel() or boundedElastic(), you are telling Java to get rid of the single-thread hurdle and use the full power of the hardware. Go ahead and play around with those Schedulers, but don't blame me if you accidentally create a thousand threads and your laptop starts sounding like a jet engine ready for takeoff 😂. Until then, bye bye!
Senior Software Engineer | Distributed Systems | Kafka | 7M+ Events/Day | Java, Python | AI Agents (GPT)
In continuation to previous post https://bit.ly/4bsoGg0 Once you get basics of Reactive programming, it becomes more interesting as we delve into further details. Let's talk about further components which come from libraries like Project Reactor. There are something called Mono and Flux. Both are different types of Publishers supported in reactive programming. Understanding these is as simple as reading a line of code. With the concept of Mono and Flux, you deal with a stream of data and not just the static data itself. Lets break it with an example. When we are fetching a unique user from a database based on id, we use Mono. Mono deals with fetching at most one object (0 or 1) or an error. Flux can be used to fetch 0 to N number of items, like a list of active users from a database. Instead of going into more details and confusing you, let's talk about other buzz words we use in reactive programming. Operators: In reactive programming, we don't just "get" data. We transform it as it flows. There are different operators which can be used for transformation without those for-loops which we were bound to use in imperative Java. Map: For synchronous transformation, like changing the type of a variable on the fly. FlatMap: Used for asynchronous transformations, like performing a database call for every item in a Flux. Filter: Filter out only the data which meets a given criteria. Concept of Backpressure: A very critical concept which should be carefully used in reactive programming; otherwise, the situation could go worse than imperative programming. Backpressure is a concept where the consumer can send a signal to the producer like "Hey, slow down, I can only handle five items at a time right now." In this way, the system maintains its own balance and eventual crashing of an application can be prevented. A Simple Example: Look at the logic below. In older Java, you'd wait for the whole list. In Reactive, you handle it as it comes. The stream starts, filters out the "C++" hurdle, transforms the rest, and then finally prints them. No curly brace hurdles, no complex declarations. Trust me, once you start thinking in streams, going back to the old way feels like taking a step backward. It might take extra time to master the operators, but the ultimate satisfaction of building a non-blocking, resilient system is worth the effort.
To view or add a comment, sign in
-
-
Is Async Reactive Programming Losing Its Edge in the Era of Virtual Threads? For over a decade, async reactive programming has been the go-to approach for building highly concurrent Java applications. It delivers impressive throughput and enables systems to handle massive workloads efficiently. But let’s be honest — it comes with trade-offs: • Debugging with async code is challenging. • Developers must be disciplined enough to avoid blocking calls. • Understanding callbacks and reactive flows requires a certain level of expertise. • The learning curve can be steep for new team members unfamiliar with the async paradigm. With the official release of Virtual Threads in Java 21, things are getting interesting. Virtual threads aim to simplify high-concurrency programming. The idea is conceptually similar to async models — non blocking tasks are efficiently scheduled to OS thread pool and system resources are fully utilized. However, the developer experience is very different. Virtual threads address many of the pain points of async programming: • Debugging feels more natural. • Code remains simple and readable. • Developers can write straightforward blocking-style code without the complexity of callbacks or reactive chains. The primary guidance? 👉 Use virtual threads for blocking operations. 👉 Don’t pool virtual threads and don't use shared thread pool. So the big question is — Will virtual threads gradually replace async reactive programming, or will both approaches continue to coexist based on use case? Curious to hear how others are approaching this in post Java 21.
To view or add a comment, sign in
-
You might have seen this code block in the top leetcode submission of a problem or in competitive programming solution such as codeforces. But what does it do, what's the need of it ? Let's understand this...... What's happening here ? In java as we all know a static block runs only once when the class is loaded by the JVM. So for every problem this part runs once and create a object of the "Solution" class before running any other part of the code. But what is the benefit of it, isn't it making the code slower as an extra code is running before the actual solution code? The answer is not really, instead it is making the code faster, how ? In a java program, when the program loads in the "JVM(Java Virtual Machine)", the JVM loads the "Solution" class and immediately the static blocks executes and create a object of the Solution class and calls the function multiple times with a dummy input. At that exact time what is happening is before running anything else, the program is warming up(yes warming up) by running that method 500 times. In Java, the JIT (Just-In-Time compiler) optimizes code after it runs a few times. Calling a method 500 times before using it ensures the method is "hot" (optimized) when real input comes. Why this is used ? In competitive programming, where execution time is critical, even small optimizations matter. This static warm-up trick leverages JVM behavior to gain a slight performance edge.
To view or add a comment, sign in
-
-
🚀 Constructors in Java—Explained from Beginner to Pro Ever wondered what really happens when we write: new Student(); Behind the scenes, a Constructor is doing the magic. ✨ 🔹 What is a Constructor? A constructor is a special method used to initialize an object when it is created. ✔ Same name as class ✔ No return type (not even void) ✔ Called automatically when object is created Example: class Student { Student() { System.out.println("Object created"); } } When you write → new Student(); The constructor runs automatically. 🟢 Types of Constructors in Java 1️⃣ Default Constructor If you don’t write any constructor, Java provides one automatically. 2️⃣ No-Argument Constructor Constructor without parameters. 3️⃣ Parameterized Constructor Used to initialize values during object creation. Student s = new Student("Shubhi", 25); 🟡 Constructor Overloading Multiple constructors in the same class with different parameters. ✔ Same name ✔ Different parameter list This helps create objects in different ways. 🔴 Constructor Chaining using this() Used to call one constructor from another constructor of the same class. Example: class Student { Student() { this("Unknown"); } Student(String name) { System.out.println(name); } } Avoids duplicate code and makes design clean. 🧠 Interview Facts Most Developers Miss ✅ Constructor is NOT inherited ✅ Cannot be static ✅ Cannot have return type ✅ Can be overloaded ✅ Parent constructor runs before child constructor 💡 Real-World Analogy Constructor = Birth Certificate of an Object When an object is created, the constructor assigns identity and initial data. 🔥 Why Constructors Matter in Real Projects? ✔ Mandatory initialization ✔ Used heavily in Dependency Injection (Spring) ✔ Helps create immutable objects ✔ Improves code safety and design If you are preparing for Java interviews, mastering constructors is non-negotiable. #Java #Programming #SoftwareEngineering #InterviewPreparation #SpringBoot #Developers #Coding
To view or add a comment, sign in
-
Constructor Chaining in Java 🔗 One Constructor Calls Another — Building a Unified Object While learning deeper into Java OOPS, one concept that truly shows structured design is Constructor Chaining. 💡 What is Constructor Chaining? Constructor chaining is the process where one constructor calls another constructor within the same class using the this() keyword. Instead of repeating initialization logic in every constructor, we delegate responsibility step by step. It’s not just about syntax — it’s about design thinking. 🔁 How the Flow Works Imagine a class with: • A 0-parameter constructor • A single-parameter constructor • A parameterized constructor The parameterized constructor can call the single-parameter constructor. The single-parameter constructor can call the 0-parameter constructor. Execution flows downward first, and once the base constructor finishes, control returns upward — completing the object creation process. This creates a clean and consistent initialization flow. 🧠 Why It Matters Without constructor chaining: Initialization code gets repeated Maintenance becomes difficult Bugs increase due to inconsistency With constructor chaining: Code duplication is avoided Initialization is centralized Objects are guaranteed to be properly built 🚀 The Real Takeaway Constructor chaining ensures that every object is created in a controlled and structured way. It’s a small concept — but it reflects professional-level design. Because in real-world development, it’s not about just creating objects… It’s about creating them correctly. TAP Academy Sharath R #Java #OOPS #SoftwareEngineering #CleanCode #Programming #TechCommunity
To view or add a comment, sign in
-
-
In Java, immutability is not “a functional programming feature.” It’s a pragmatic engineering tool that improves object-oriented design and unlocks more functional styles of programming. This article builds the concept from an OOP perspective first, then reframes it through a functional lens. https://lnkd.in/eCAKTvw3
To view or add a comment, sign in
-
Mastering Object Initialization: A Deep Dive into Java Constructors 🏗️☕ When we talk about Object-Oriented Programming, we often focus on the "what" (Classes) and the "how" (Methods). But the "When" is just as important—and that is where Constructors come in. Think of a constructor as the "Building Crew" of your code. It’s the very first block of code that runs to set the foundation for every new object you create. 🧱 🔍 What is a Java Constructor? As shown in the guide, a constructor is a special method used to initialize objects. It has three unique rules: It must have the same name as the class. It has no return type (not even void). It is called automatically the moment you use the new keyword. The Three Musketeers of Initialization: 1️⃣ Default Constructor (The Auto-Builder) 📦 Role: If you don't write a constructor, Java provides one for you. Function: It initializes your fields with default values like 0, false, or null. Analogy: It’s like buying a "standard" house model—it comes with the basic layout already set. 2️⃣ Parameterized Constructor (The Custom Architect) 🛠️ Role: Allows you to pass specific data during object creation. Function: It lets you set unique initial values for different objects. Analogy: This is a custom-built home. You tell the builder exactly what color you want and how many windows to install from day one. 3️⃣ Copy Constructor (The Perfect Clone) 📑 Role: Initializes a new object using the values of an existing object. Function: It creates a distinct, new instance that is a "copy" of another. Analogy: You see a house you love and tell the builder, "Build me exactly what they have!" 💡 Why should you care? Properly using constructors ensures your objects start their "life" in a valid state. It prevents "null pointer" headaches and makes your code more predictable and professional. Which constructor do you find yourself using the most in your daily projects? Let's talk shop in the comments! 👇 #Java #OOP #Coding #SoftwareEngineering #JavaDeveloper #TechTutorial #ProgrammingTips
To view or add a comment, sign in
-
-
Source Code is the Source of Truth: who ought to understand it? Source code is the code written at the abstraction layer and in the language we regularly read and modify - thus must understand. It is the ultimate system specification and definition - documentation comes and goes, gets outdated frequently and more often than not skips on important details. From the source code, the system is created - it is always true, always up to date and every detail is spelled out there. Since it is the most important artifact of the system - the Definition - the art of writing code as clearly, simply and unambiguously as possible has been and will always remain of key importance. With the programming languages, we have been steadily increasing their abstraction level, pretty much since the very inception of the software development craft. From the binary machine code to assembly, from assembly to C, and from C to high-level programming languages of today: Java, C#, JavaScript, Python and so on. Yesterday's source code was written in machine code and assembly; today's is in one of those high-level programming languages. As LLMs and agentic coding tools built on top of them has been learning to generate source code, some of their avid supporters began to argue: "We should not look at the source code any longer! Given detailed specification, LLMs can generate code according to what was fed to them; checking and reviewing the output only slows the process down. Humans are the bottleneck!" But, if we no longer look at the source code - which is the ultimate system definition - what control, understanding and quality assurances of the system do we have? As long as there is software, there is the source code - the code written at the abstraction layer and in the language we regularly read and modify. One day, we might start to use even higher-level than today's popular programming languages are, resembling English more, maybe even more suitable for LLMs to work with - although I remain sceptical, since with every abstraction level raise, we lose another degree of control and ability to customize as well. So, if writing highly detailed English prompts allows you to get desired Java, C#, JavaScript or Python system specifications more efficiently, by all means do it! But as long as this is our source code, and not English prompts for LLMs to generate something else, we are responsible for being able to read, understand, explain, modify and make sense of it all.
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development
Excellent explanation 👌