So far, we used : Runnable But Runnable has a limitation: ❌ It cannot return a result ❌ It cannot throw checked exceptions That’s where Callable comes in. Callable<Integer> task = () -> 10 + 20; Unlike Runnable: ✅ It returns a value ✅ It can throw exceptions Now combine it with ExecutorService: import java.util.concurrent.*; ExecutorService executor = Executors.newSingleThreadExecutor(); Callable<Integer> task = () -> 10 + 20; Future<Integer> future = executor.submit(task); System.out.println("Doing other work..."); Integer result = future.get(); // waits if needed System.out.println("Result: " + result); executor.shutdown(); What is Future? A Future represents the result of an asynchronous computation. It allows you to: • Check if task is done → isDone() • Cancel task → cancel() • Get result → get() Important: future.get(); This blocks until result is ready. So even in concurrency, blocking can still happen. The Big Idea Instead of: Run → Wait → Continue We now: Run → Do other work → Collect result later That’s asynchronous thinking. Today was about: • Difference between Runnable & Callable • What Future represents • How asynchronous execution works Modern systems don’t wait. They schedule, continue, and respond when ready. And now… so can your Java programs. #Java #Concurrency #Callable #Future #Multithreading #AsynchronousProgramming #LearningInPublic
Callable vs Runnable: Understanding Java Concurrency with Future
More Relevant Posts
-
💡 What actually happens inside the JVM when a Java program runs? Many developers write Java code every day but rarely think about what happens inside the JVM. Here’s a simplified view of JVM memory 👇 🧠 1. Heap Memory This is where all objects live. Example: "User user = new User();" The object is created in the Heap. Garbage Collector (GC) cleans unused objects from here. --- 📦 2. Stack Memory Every thread gets its own stack. It stores: • Method calls • Local variables • References to objects in Heap When a method finishes, its stack frame disappears automatically. --- ⚙️ 3. Metaspace (Method Area) Stores class-level information like: • Class metadata • Method definitions • Static variables • Runtime constant pool Unlike older JVMs, this lives in native memory, not heap. --- 🔁 4. Program Counter Register Tracks which instruction the thread is currently executing. Think of it like a bookmark for the JVM. --- 🔥 Simple flow Code → Class Loader → JVM Memory → Execution Engine → Garbage Collection Understanding JVM internals helps you: ✔ Debug memory leaks ✔ Understand GC behaviour ✔ Optimize performance Great developers don’t just write code. They understand how the runtime actually works. What JVM concept confused you the most when you first learned it? #Java #JVM #JavaDeveloper #SoftwareEngineering #BackendDevelopment
To view or add a comment, sign in
-
-
“Where does data actually live in Java… Stack or Heap?” Not how to write the code. But what really happens in memory when the code runs. When a Java program runs, memory is mainly divided into two places. Stack and Heap. Here’s the simple way to think about it. The Stack stores method calls and local variables. Every time a method runs, a new stack frame is created. When the method finishes, that frame disappears. It’s fast, structured, and managed automatically. The Heap, on the other hand, is where objects actually live. Whenever you create something with new, the object goes into the heap. The stack only keeps the reference pointing to that object. So something like this: Person p = new Person(); What really happens is: ↳ p (reference) lives in the stack ↳ Person object lives in the heap This small distinction explains a lot of things developers struggle with: • why objects persist beyond a method call • how memory leaks happen • how garbage collection works • why references behave the way they do Sometimes the hardest part of software engineering isn’t writing code. It’s understanding what the runtime is doing behind the scenes. How do you usually explain Stack vs Heap to someone learning Java? #Java #SoftwareEngineering #Programming #JavaDeveloper #Coding
To view or add a comment, sign in
-
-
💡 Java isn’t as simple as “new Object() = heap memory” Most developers learn: 👉 new Object() → Heap allocation 👉 Reference → Stack ✔️ Good for basics… but not the full story. 🚀 What really happens in modern Java? With JIT (Just-In-Time Compiler), the JVM can optimize away object creation completely. Yes, you read that right. void process() { Object obj = new Object(); System.out.println(obj.hashCode()); } 👉 If obj is used only inside the method and doesn’t “escape” ➡️ JVM may: Skip heap allocation ❌ Allocate on stack ⚡ Or eliminate the object entirely 🔥 🧠 The core concept: Escape Analysis If an object: ❌ Does NOT leave the method → Optimized ✅ Escapes (returned, shared, stored) → Heap allocation ⚠️ Common misconception ❌ “Avoid creating objects to save memory” ✔️ Reality: JVM is smarter than that Premature optimization can: Make code ugly Reduce maintainability Give no real performance gain 🔧 Static vs Object? ✔️ Use static when no state is needed ✔️ Use objects when behavior depends on data 👉 It’s not about avoiding new 👉 It’s about writing clean, logical design 🏁 Final takeaway Java is not just compiled — it adapts at runtime 🔥 The JVM decides: What to allocate What to remove What to optimize 👨💻 Write clean code. 📊 Measure performance. ⚡ Trust the JVM. #Java #JVM #Performance #Backend #SoftwareEngineering #CleanCode
To view or add a comment, sign in
-
🚀 Java 25 is HERE — and it’s a GAME-CHANGER! ☕💥 👩🎓Forget boilerplate. Forget clunky code. Java 25 (JDK 25 LTS) makes your code simpler, faster, and smarter. Developers are LOVING it already. 🔥 Top Features Everyone’s Talking About: 1️⃣ Compact Source Files – No public static void main needed. Run code like a script! 2️⃣ Scoped Values – Safer, cleaner concurrency. Goodbye messy ThreadLocals. 3️⃣ Pattern Matching for Primitives – Write less, do more. 4️⃣ Flexible Constructors – Validation before super()? Yes please! 5️⃣ Better Performance & Memory – Smaller object headers, faster GC. 6️⃣ Advanced Profiling & Observability – Java Flight Recorder upgraded. 📚 Official Docs & Release Notes: ✅ Java 25 Documentation & What’s New — https://lnkd.in/gpPyzmta ✅ JDK 25 Release Notes (full details) — https://lnkd.in/g8ExzNRf 💡 Why Java 25 is viral-worthy: 🔹Beginners can start coding without drowning in boilerplate. 🔹Enterprise apps get LTS stability + better performance. 🔹Modern features for cloud, AI, and microservices. ⚡ Pro Tip: Try writing: void main() { IO.println("Hello, Java 25!"); } It just works. Mind blown, right? 🤯 💬 Your turn: Are you ready to ditch old Java habits and level up with Java 25? Drop a 🚀 if you are! #Java25 #JDK25 #Java #Programming #SoftwareDevelopment #Parmeshwarmetkar #DevCommunity #TechTrends #CodingLife #FullStack
To view or add a comment, sign in
-
Your Java code might be slow before it even runs. ☕ Most beginners ignore object creation cost. They create new objects inside loops. Thousands of objects appear in seconds. Garbage collector now has extra work. Small inefficiency becomes large latency. Rule: reuse objects when possible in hot paths. Takeaway: memory churn quietly slows backend systems. 🧠 Where did you accidentally create objects in a loop? #CoreJava #JavaPerformance #BackendDevelopment
To view or add a comment, sign in
-
-
The "1MB Problem" that almost killed Java scaling. 🧱📉 For 25 years, Java developers were trapped. Every new Thread() you created was a 1-to-1 mapping to an Operating System (OS) thread. The cost? Roughly 1MB of stack memory per thread. Do the math for a high-scale system: 1,000 concurrent users = 1GB of RAM just for the existence of threads. 10,000 users? Your JVM is likely hitting an OutOfMemoryError before your business logic even executes. This "Threading Wall" is exactly why Reactive Programming (WebFlux) became the standard. We traded readable, imperative code for complex, "callback-hell" chains just to save memory. But it’s 2026, and the wall has been torn down. With Java 21 and the refinements in JDK 25, we’ve finally decoupled "Execution" from "Hardware." We no longer need to choose between "Easy to Code" and "Easy to Scale." Over the next 7 days, I’m doing a deep dive into the Modern Java Concurrency Stack. We aren't just talking about theory; we’re looking at how these shifts enable the next generation of AI-Orchestrated Backends (like the Travel Agent RAG I’m currently building). #Takeaway: If you are still building heavy thread pools for I/O-bound tasks, you are solving a 2015 problem with 2015 tools. Are you still fighting the "1MB Problem" with Reactive code, or have you fully migrated to the Loom (Virtual Thread) era? Let’s talk architecture below. 👇 #Java25 #SpringBoot4 #SystemDesign #HighScale #BackendEngineering #SDE2 #SoftwareArchitecture #Concurrency
To view or add a comment, sign in
-
🚀 Build a 𝗛𝗶𝗴𝗵-𝗣𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲, 𝗧𝗵𝗿𝗲𝗮𝗱-𝗦𝗮𝗳𝗲 Java Logging Framework I designed and implemented a 𝗖𝘂𝘀𝘁𝗼𝗺 𝗝𝗮𝘃𝗮 𝗟𝗼𝗴𝗴𝗶𝗻𝗴 𝗙𝗿𝗮𝗺𝗲𝘄𝗼𝗿𝗸 from scratch, focusing on performance, thread safety, and reusability across multiple modules instead of relying on existing logging libraries. The objective was to build a modular, extensible, and thread-safe logging utility that can be reused across Spring Boot applications. 🏗️ Architecture Highlights • 𝗙𝗮𝗰𝘁𝗼𝗿𝘆 𝗣𝗮𝘁𝘁𝗲𝗿𝗻 → Centralized logger creation using LoggerFactory • 𝗦𝗶𝗻𝗴𝗹𝗲𝘁𝗼𝗻 𝗽𝗲𝗿 𝗖𝗹𝗮𝘀𝘀→ Managed using ConcurrentHashMap<String, CustomLogger> • Thread-safe initialization using computeIfAbsent() • 𝗦𝘁𝗿𝗮𝘁𝗲𝗴𝘆 𝗣𝗮𝘁𝘁𝗲𝗿𝗻 → Separate Formatter, Writer, and Level handling • 𝗣𝗮𝗰𝗸𝗮𝗴𝗲𝗱 𝗮𝘀 𝗿𝗲𝘂𝘀𝗮𝗯𝗹𝗲 𝗝𝗔𝗥 → Plug-and-play across Controller / Service / Repository layers ⚡ Key Technical Points • 𝗟𝗼𝗰𝗸-𝗳𝗿𝗲𝗲 𝗰𝗼𝗻𝗰𝘂𝗿𝗿𝗲𝗻𝗰𝘆 𝘂𝘀𝗶𝗻𝗴 𝗖𝗼𝗻𝗰𝘂𝗿𝗿𝗲𝗻𝘁𝗛𝗮𝘀𝗵𝗠𝗮𝗽. • One logger instance per class (singleton strategy) • Multi-module reusable logging library • Clean separation of concerns following SOLID principles • Designed for safe usage in multi-threaded environments 🔄 Flow Application Layer → LoggerFactory → ConcurrentHashMap Cache → CustomLogger → Formatter / Level / Writer → Console Output The framework is packaged as a reusable library and integrated into a Spring Boot project to simulate real-world multi-layer usage. GitHub: https://lnkd.in/gKpGZrCy This project focuses on practical low-level design, concurrency, and reusable library architecture. #Java #SystemDesign #LowLevelDesign #Concurrency #SpringBoot #DesignPatterns #BackendDevelopment #SoftwareArchitecture
To view or add a comment, sign in
-
-
Java records are powerful. But they are not a replacement for every POJO. That is where many teams get the migration decision wrong. A record is best when your type is mainly a transparent carrier for a fixed set of values. Java gives you the constructor, accessors, equals(), hashCode(), and toString() automatically, which makes records great for DTOs, request/response models, and small value objects. But records also come with important limits. A record is shallowly immutable, its components are fixed in the header, it cannot extend another class because it already extends java.lang.Record, and you cannot add extra instance fields outside the declared components. You can still add validation in a canonical or compact constructor, but records are a poor fit when the model needs mutable state, framework-style setters, or inheritance-heavy design. So the real question is not: “Should we convert all POJOs to records?” The better question is: “Which POJOs are actually just data carriers?” That is where records shine. A practical rule: use records for immutable data transfer shapes, keep normal classes for JPA entities, mutable domain objects, lifecycle-heavy models, and cases where behavior and state evolve over time. Also, one important clarification: this is not really a “Java 25 only” story. Records became a permanent Java feature in Java 16, and Java 25 documents them as part of the standard language model. So no, the answer is not “change every POJO to record.” Change only the POJOs that truly represent fixed data. Where do you draw the line in your codebase: DTOs only, or value objects too? #Java #Java25 #JavaRecords #SoftwareEngineering #BackendDevelopment #CleanCode #JavaDeveloper #Programming #SystemDesign #TechLeadership
To view or add a comment, sign in
-
-
JVM Is Not “Compile Once, Run Anywhere” We all learned: Java = Write once, run anywhere. Reality in production: Java = Compile once, optimize everywhere. Your code runs as: .java → .class (bytecode) → JIT → machine code But here’s the catch: - First execution = slow (interpreted) - Hot code = optimized (JIT compiled) Example: for (int i = 0; i < 1_000_000; i++) { process(i); } First few runs: - Slower Later runs: - Much faster (JIT kicks in) 💡 Real-world impact: - First API calls in production may be slower - Warm-up matters in performance testing 💡 Takeaway: Java performance improves over time — not instantly. #Java #JVM #Performance #BackendEngineering
To view or add a comment, sign in
-
Today, with records, better IDE support, and a much more mature Java, adding Lombok to every new project feels a bit like installing turbo in a Corolla just to go to the bakery. That said, I wouldn’t turn this into a holy war. In legacy systems, Lombok can still be practical. But for new code, I agree: prefer plain modern Java first, and add dependencies only when they solve a real problem. Less magic, less hidden code, fewer surprises after a JDK upgrade. At this point, modern Java is basically saying: “Thanks Lombok, we got it from here.”
Director of Engineering @ BNY • Java Champion • Google Developer Expert in Angular • Microsoft MVP • Oracle ACE • Published Author
You don't need Lombok anymore. 🌶️ For years, Lombok was the answer to Java's boilerplate problem. Getters, setters, constructors, toString, equals, hashCode... one annotation and done. Unfortunately, a lot of YouTube tutorials and courses are still teaching this practice. But Java has caught up, and it's time to update the playbook. Lombok hooks into javac internals. Every JDK upgrade risks breakage. It's an annotation processor with deep access to your build. That's supply chain risk. Generated code is invisible to debuggers. You can't step through what doesn't exist in source. @Data generates public setters with zero validation. Any code can put your object in an invalid state. Records can fix this. Validate once at construction, no setters to bypass, immutable by default. Even for JPA entities where records don't work, your IDE generates the boilerplate in seconds. It's a one-time cost. My recommendation: stop adding Lombok to new code. Use records for data carriers. Leave plain Java classes for JPA entities only. Migrate gradually. 👉 **The best dependency is the one you don't need. I wrote a full annotation-by-annotation migration guide with before/after code examples for every Lombok feature: 🔗 https://lnkd.in/eHVJ5tQJ #Java #Lombok #ModernJava #CleanCode
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