Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

ความแตกต่างระหว่าง Runnable และ Callable Interface ใน Java

ความแตกต่างระหว่าง Runnable และ Callable ใน Java

ทั้งสองเป็น Functional Interface สำหรับ Multithreading แตกต่างกันที่ ค่าส่งคืน, ข้อยกเว้น, และ วิธีการรัน

ตารางเปรียบเทียบ

คุณสมบัติ Runnable Callable<V>
Package java.lang java.util.concurrent
เมธอดหลัก void run() V call() throws Exception
ค่าส่งคืน ไม่มี (void) มี (Generic Type V)
Checked Exception ไม่สามารถโยนได้ โยนได้ (throws Exception)
การรัน Thread new Thread(runnable).start() ต้องใช้ ExecutorService
ผลลัพธ์ Async ไม่ได้โดยตรง Future<V> จาก submit()
Bulk Execution ไม่รองรับ invokeAll(), invokeAny()
Functional Interface ✅ (Single Abstract Method) ✅ (Single Abstract Method)

ตัวอย่าง Runnable

public class RunnableExample implements Runnable {
    @Override
    public void run() {
        System.out.println("Hello from Runnable! Thread: " + Thread.currentThread().getName());
    }
    
    public static void main(String[] args) {
        // วิธี 1: Thread constructor
        new Thread(new RunnableExample()).start();
        
        // วิธี 2: Lambda (Java 8+)
        new Thread(() -> System.out.println("Lambda Runnable")).start();
        
        // วิธี 3: Anonymous class
        new Thread(new Runnable() {
            @Override public void run() {
                System.out.println("Anonymous Runnable");
            }
        }).start();
    }
}

ตัวอย่าง Callable

import java.util.concurrent.*;

public class CallableExample implements Callable {
    @Override
    public String call() throws Exception {
        System.out.println("In call() - Thread: " + Thread.currentThread().getName());
        Thread.sleep(1000); // จำลองงานหนัก
        return "Result from Callable";
    }
    
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        
        // Submit คืนค่า Future
        Future future = executor.submit(new CallableExample());
        
        System.out.println("Main thread doing other work...");
        
        // get() บล็อกจนกว่าจะได้ผลลัพธ์
        String result = future.get(); 
        System.out.println("Result: " + result);
        
        executor.shutdown();
    }
}

ผลลัพธ์ Callable

Main thread doing other work...
In call() - Thread: pool-1-thread-1
Result: Result from Callable

การใช้งาน Callable แบบทันสมัย (Java 8+ Lambda)

ExecutorService executor = Executors.newFixedThreadPool(3);

List> tasks = List.of(
    () -> { Thread.sleep(100); return 1; },
    () -> { Thread.sleep(200); return 2; },
    () -> { Thread.sleep(300); return 3; }
);

// รันทั้งหมดรอจบ (invokeAll)
List> futures = executor.invokeAll(tasks);
for (Future f : futures) {
    System.out.println("Result: " + f.get());
}

// รันใครเร็วสุดเอา (invokeAny)
Integer fastest = executor.invokeAny(tasks);
System.out.println("Fastest result: " + fastest);

executor.shutdown();

CompletableFuture (Java 8+) - ทันสมัยกว่า

// Non-blocking, composable
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
    // Heavy computation
    return "Async Result";
});

future.thenAccept(result -> System.out.println("Got: " + result));
// หรือ
String result = future.join(); // Blocking

แนวทางเลือกใช้

  • Runnable: งานที่ไม่ต้องส่งค่ากลับ (Fire-and-forget, Logging, Background tasks)
  • Callable: งานที่ต้องการผลลัพธ์ คำนวณซับซ้อน อาจโยน Exception
  • CompletableFuture: Async programming ทันสมัย Chaining, Combining, Exception handling ดีกว่า
  • Virtual Threads (Java 21+): ใช้ Runnable ธรรมดา แต่ Scalability สูงมาก