🔥 Day 10 — Thread vs Runnable vs Callable in Java If you're working with concurrency in Java, you’ll constantly decide between Thread, Runnable, and Callable. Here’s a simple, practical breakdown 👇 1️⃣ Thread — The Oldest & Loudest Way Thread represents an actual execution thread. ✔ When to use - Only when you must override thread-specific behavior - Very rare in modern applications ✖ Why it's not preferred - You can’t return a result - You can’t throw checked exceptions Tight coupling: your task is also the thread Check below example: class MyThread extends Thread { public void run() { System.out.println("Running thread"); } } 2️⃣ Runnable — Lightweight Tasks (No Return Value) Runnable is the simplest abstraction for a task. ✔ When to use - You just need to run a piece of code - No result required For example : Runnable task = () -> System.out.println("Task running"); executor.submit(task); 3️⃣ Callable — Runnable with Superpowers ⚡ Callable<V> is Runnable’s upgraded version. ✔ Key advantages - Returns a value - Can throw checked exceptions - Works seamlessly with Future ✔ When to use - When your task computes a result - When you need exception handling For example: Callable<Integer> task = () -> 42; Future<Integer> result = executor.submit(task); 💡 Key Takeaway Stop creating your own Thread. - Use Runnable when you need simple execution, - Use Callable when you need a result or exception handling. #100DaysOfJavaArchitecture #Java #Concurrency #SoftwareArchitecture #Microservices
Java Concurrency: Thread, Runnable, Callable Explained
More Relevant Posts
-
💡 Decouple Your Tasks: Understanding the Java ExecutorService 🚀 Are you still manually managing new Thread() in your Java applications? It might be time to level up to the ExecutorService! I've been reviewing concurrency patterns recently and put together this quick overview of why this framework (part of java.util.concurrent) is crucial for building robust, scalable software. The core idea? Stop worrying about the threads and start focusing on the tasks. The ExecutorService decouples task submission from task execution. Instead of your main code managing thread lifecycles, you give the task (a Runnable or Callable) to the ExecutorService. It acts as a smart manager with a dedicated team (a thread pool) ready to handle the workload. Check out the diagram below to see how it works! 👇 Why should you use it? 1️⃣ Resource Management: Creating threads is expensive. Reusing existing threads in a pool saves overhead and prevents your application from exhausting system memory. 2️⃣ Controlled Concurrency: You control the number of threads. You can't overwhelm your CPU if you limit the pool size. 3️⃣ Cleaner Code: It separates the work (your tasks) from the mechanism that runs it (threading logic). Here is a quick example of a Fixed Thread Pool in action: Java // 1. Create a managed pool (3 threads) ExecutorService manager = Executors.newFixedThreadPool(3); // 2. Submit your work (it goes to the queue first) manager.submit(() -> { System.out.println("🚀 Processing data on: " + Thread.currentThread().getName()); }); // 3. Clean up (vital!) manager.shutdown(); Which type of Thread Pool do you find yourself using the most in your projects? (Fixed, Cached, or Scheduled?) Let's discuss in the comments! 👇 #Java #Programming #Concurrency #SoftwareEngineering #Backend #TechTips
To view or add a comment, sign in
-
-
📌 Exception Handling in Java — Understanding Exception Propagation The diagram represents how Java manages exceptions using the call stack and identifies the appropriate handler. 🔹 Execution Flow: • An exception is thrown in "divideByZero()" • The method does not handle it → exception is propagated • "computeDivision()" receives the exception but does not handle it • The exception continues to propagate up the call stack • "main()" contains the appropriate "catch" block and handles the exception 🔹 Internal Mechanism: The JVM performs stack unwinding, examining each method in the call stack sequentially to locate a matching exception handler. If no handler is found, the program terminates and a stack trace is generated. 🔹 Key Takeaways: • Exception propagation ensures centralized and structured error handling • Not every method should handle exceptions — only where recovery is possible • Proper handling improves system stability and maintainability 🔹 Best Practices: ✔ Catch specific exceptions instead of generic ones ✔ Avoid unnecessary try-catch blocks ✔ Use meaningful logging for debugging and monitoring ✔ Rethrow exceptions with additional context when needed ✔ Design applications with clear error-handling strategies 🔹 Conclusion: Effective exception handling is not just a language feature — it is a critical part of designing robust and maintainable systems. #Java #ExceptionHandling #SoftwareEngineering #BackendDevelopment #CleanCode
To view or add a comment, sign in
-
-
🚀 Exploring CompletableFuture in Java (When to use & when to avoid) While revisiting Java 8 concepts, I explored CompletableFuture and how it helps in handling asynchronous operations. 💡 A common backend scenario: An API needs to call multiple services: User Service Order Service Payment Service If executed sequentially: getUser(); getOrder(); getPayment(); ⏱️ Total time increases as each call waits for the previous one. 👉 Using CompletableFuture, we can execute them in parallel: CompletableFuture<String> user = CompletableFuture.supplyAsync(() -> getUser()); CompletableFuture<String> order = CompletableFuture.supplyAsync(() -> getOrder()); CompletableFuture<String> payment = CompletableFuture.supplyAsync(() -> getPayment()); CompletableFuture.allOf(user, order, payment).join(); ⚡ Independent tasks run concurrently → better performance ✅ When to use CompletableFuture: Calling multiple independent APIs Microservices communication Improving response time Parallel data fetching ⚠️ When to avoid: When tasks depend on each other Heavy blocking operations (like DB calls without proper thread management) Small/simple logic where async adds complexity 📌 My takeaway: Even if not used directly yet, understanding where it fits helps design better scalable systems. Looking forward to applying this in real projects. Have you used CompletableFuture in your applications? Any challenges or best practices? 👇 #Java #SpringBoot #BackendDevelopment #Microservices #CompletableFuture #JavaDeveloper #SoftwareEngineering
To view or add a comment, sign in
-
✅ Java Exceptions: 9 Best Practices You Can’t Afford to Ignore Whether you're just starting out or you've been coding for years — exception handling in Java can still trip you up. 🧠 Let's revisit some timeless practices that keep your code clean, your logs useful, and your team productive. 🔹 Always free resources – Use finally or try-with-resources, never close in the try block itself. 🔹 Be specific – NumberFormatException > IllegalArgumentException. Specific exceptions = better API usability. 🔹 Document your exceptions – Add @throws in Javadoc so callers know what to expect. 🔹 Write meaningful messages – 1–2 sentences that explain the why, not just the what. 🔹 Catch most specific first – Order your catch blocks from narrowest to broadest. 🔹 Never catch Throwable – You'll also catch OutOfMemoryError and other unrecoverable JVM issues. 🔹 Don't ignore exceptions – No empty catches. At least log it! 🔹 Don't log and rethrow the same exception – That duplicates logs without adding value. 🔹 Wrap when adding context – Create custom exceptions but always keep the original cause. 💡 Clean exception handling = better debugging + happier teammates. 👉 Which of these best practices does your team struggle with most? Let me know in the comments! #Java #ExceptionHandling #CleanCode #SoftwareEngineering #ProgrammingBestPractices #JavaDeveloper #CodingTips #ErrorHandling #JavaProgramming #CodeQuality #BackendDevelopment #TechBestPractices
To view or add a comment, sign in
-
-
📌 Optional in Java — Avoiding NullPointerException NullPointerException is one of the most common runtime issues in Java. Java 8 introduced Optional to handle null values more safely and explicitly. --- 1️⃣ What Is Optional? Optional is a container object that may or may not contain a value. Instead of returning null, we return Optional. Example: Optional<String> name = Optional.of("Mansi"); --- 2️⃣ Creating Optional • Optional.of(value) → value must NOT be null • Optional.ofNullable(value) → value can be null • Optional.empty() → represents no value --- 3️⃣ Common Methods 🔹 isPresent() Checks if value exists 🔹 get() Returns value (not recommended directly) --- 4️⃣ Better Alternatives 🔹 orElse() Returns default value String result = optional.orElse("Default"); 🔹 orElseGet() Lazy default value 🔹 orElseThrow() Throws exception if empty --- 5️⃣ Transforming Values 🔹 map() Optional<String> name = Optional.of("java"); Optional<Integer> length = name.map(String::length); --- 6️⃣ Why Use Optional? ✔ Avoids null checks everywhere ✔ Makes code more readable ✔ Forces handling of missing values ✔ Reduces NullPointerException --- 7️⃣ When NOT to Use Optional • As class fields • In method parameters • In serialization models --- 🧠 Key Takeaway Optional makes null handling explicit and safer, but should be used wisely. It is not a replacement for every null. #Java #Java8 #Optional #CleanCode #BackendDevelopment
To view or add a comment, sign in
-
🚀 CyclicBarrier in Java — Small Concept, Powerful Synchronization In multithreading, coordination between threads is critical ⚡ 👉 CyclicBarrier allows multiple threads to wait for each other at a common point before continuing — ensuring everything stays in sync 🔥 💡 Think of it like a checkpoint 🏁 No thread moves forward until all have arrived! 🌍 Real-Time Example Imagine a report generation system 📊 Multiple threads fetch data from different APIs 📡 Each processes its own data ⚙️ Final report should generate only when all threads finish 👉 With CyclicBarrier, you ensure: ✅ All threads complete before aggregation ✅ No partial or inconsistent data ✅ Smooth parallel execution 💻 Quick Code Example import java.util.concurrent.CyclicBarrier; public class Demo { public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("All threads reached. Generating final report...")); Runnable task = () -> { try { System.out.println(Thread.currentThread().getName() + " fetching data..."); Thread.sleep(1000); barrier.await(); System.out.println(Thread.currentThread().getName() + " done!"); } catch (Exception e) { e.printStackTrace(); } }; for (int i = 0; i < 3; i++) new Thread(task).start(); } } 💪 Why it’s powerful ✔️ Keeps threads perfectly synchronized ✔️ Prevents incomplete execution ❌ ✔️ Reusable for multiple phases ♻️ 🔥 Final Thought 👉 It’s a small but powerful feature — use it wisely based on your project needs to ensure the right level of synchronization without overcomplicating your design. #Java #Multithreading #Concurrency #BackendDevelopment #SoftwareEngineering
To view or add a comment, sign in
-
🚀 Java Series – Day 27 📌 Stream API in Java (Real Example) 🔹 What is it? The Stream API is used to process collections of data in a functional and efficient way. It allows operations like filter, map, and reduce without using traditional loops. 🔹 Why do we use it? Streams help in: ✔ Writing clean and concise code ✔ Improving readability ✔ Handling large data efficiently For example: In an application, we can filter even numbers, transform data, or calculate results easily. 🔹 Example: import java.util.*; import java.util.stream.*; public class Main { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6); // Stream operations list.stream() .filter(n -> n % 2 == 0) // filter even numbers .map(n -> n * 2) // multiply by 2 .forEach(System.out::println); // print result } } 🔹 Output: 4 8 12 💡 Key Takeaway: Stream API helps you write less code and process data efficiently. What do you think about this? 👇 #Java #StreamAPI #JavaDeveloper #Programming #BackendDevelopment
To view or add a comment, sign in
-
-
🚀 Day 7/100 – Java Practice Challenge Continuing my #100DaysOfCode journey with another important Java concept. 🔹 Topic Covered: Exception Handling Exception handling helps to manage runtime errors and ensures the program runs smoothly without crashing. 💻 Practice Code: 🔸 Example Program public class Main { public static void main(String[] args) { int balance = 5000; try { int withdrawAmount = 6000; if (withdrawAmount > balance) { throw new Exception("Insufficient Balance!"); } balance -= withdrawAmount; System.out.println("Withdraw successful. Remaining balance: " + balance); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } finally { System.out.println("Transaction completed."); } } } 📌 Key Learnings: ✔️ Handles runtime errors effectively ✔️ Prevents application crashes ✔️ try-catch is used to handle exceptions ✔️ finally block always executes 🎯 Focus: Handles "what if something goes wrong" during program execution ⚡ Types of Exceptions: 👉 Checked Exceptions 👉 Unchecked Exceptions 🔥 Interview Insight: Exception handling is widely used in real-world applications (Banking, APIs, Microservices) to ensure reliability and stability. #Java #100DaysOfCode #ExceptionHandling #JavaDeveloper #Programming #LearningInPublic
To view or add a comment, sign in
-
Built DTOForge, a small Spring Boot tool that generates Java DTOs from JSON. Useful when integrating external APIs and you do not want to keep writing DTOs by hand. Supports: * Java records * Java classes * nested objects * arrays * optional Jackson annotations Source: `https://lnkd.in/eWEpUxPY Medium article: https://lnkd.in/eDmK-eVx #Java #SpringBoot #OpenSource #BackendDevelopment #APIIntegration
To view or add a comment, sign in
-
💡 Most Java developers still think thread creation is just: new Thread().start(); But that mindset is already outdated. Java has quietly evolved… and with Virtual Threads (Project Loom), the entire concurrency model has changed 🚀 Here’s the real shift: 👉 Traditional Threads → Heavy, 1:1 OS mapping 👉 ExecutorService → Controlled, pooled execution 👉 Virtual Threads → Lightweight, scalable, millions possible 🔥 And the most powerful pattern today? 👉 Executors.newVirtualThreadPerTaskExecutor() You get: ✔ Clean architecture (task vs execution separation) ✔ Massive scalability ✔ Simple, readable code ✔ No thread pool tuning headaches 🧠 The biggest mindset change? 👉 Don’t change your business logic 👉 Just change how it executes Same Runnable. Different execution model. That’s how modern Java systems are built. 📌 I’ve broken this down with: ✔ Complete runnable examples ✔ Traditional vs Executor vs Virtual Threads ✔ Internal working (what JVM actually does) ✔ Real-world scenarios & pitfalls 👇 Read here: https://lnkd.in/e-vdH8Vc ⚠️ If you're building backend systems and not using virtual threads yet… you’re leaving serious performance on the table. #Java #VirtualThreads #ProjectLoom #Concurrency #BackendDevelopment #Multithreading
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