PlusMagi's Blog By Pitt Phunsanit Backend,Concurrency Java Multithreading 101: การสร้าง Thread ด้วย Thread Class และ Runnable Interface

Java Multithreading 101: การสร้าง Thread ด้วย Thread Class และ Runnable Interface

ในโลกของการพัฒนาซอฟต์แวร์ระดับองค์กร (Enterprise Level) การที่แอปพลิเคชันต้องสามารถตอบสนองต่อผู้ใช้งานจำนวนมากพร้อมกัน หรือต้องทำงานที่ซับซ้อนหลายส่วนพร้อมกัน คือความท้าทายหลักที่นักพัฒนาต้องเผชิญ Multithreading จึงเป็นหัวใจสำคัญที่ทำให้ระบบมีความสามารถในการรองรับโหลดสูง (High Scalability) และมีความตอบสนองที่ดี (Responsiveness)

บทความนี้จะพาคุณไปทำความเข้าใจพื้นฐานของ Java Multithreading โดยเจาะลึกวิธีการสร้าง Thread อย่างถูกต้องตามหลักการของ Java คือการใช้ Runnable Interface และการสืบทอดจาก Thread Class ซึ่งเป็นรากฐานสำคัญก่อนก้าวไปสู่การจัดการ Synchronization ที่ซับซ้อนยิ่งขึ้น

💡 Multithreading คืออะไร และทำไมต้องใช้?

Multithreading คือกลไกที่ช่วยให้โปรแกรมสามารถทำงานหลายอย่างได้พร้อมกัน (Concurrency) โดยที่ระบบปฏิบัติการจะสลับการทำงานระหว่าง Threads เหล่านั้นอย่างรวดเร็ว

  • การเพิ่มประสิทธิภาพ: ช่วยให้งานที่ใช้เวลานาน เช่น การดาวน์โหลดไฟล์ขนาดใหญ่ สามารถรันใน Background Thread โดยไม่ทำให้ User Interface (UI) หลักค้าง (Freezing)
  • การรองรับโหลด: ในระบบ Backend (เช่น Spring Boot) เมื่อมี Request เข้ามาพร้อมกันหลายร้อยรายการ Thread Pool จะช่วยจัดการ Request เหล่านั้นอย่างมีประสิทธิภาพ

🛠️ วิธีการสร้าง Thread ใน Java: Runnable vs. Thread Class

Java มีสองแนวทางหลักในการสร้าง Thread ซึ่งนักพัฒนาควรทราบข้อดีข้อเสียของแต่ละวิธี:

1. การใช้ Runnable Interface (Recommended Approach)

การ implement Runnable คือการกำหนดงาน (Task) ที่ต้องการให้ Thread ทำงาน โดยการเขียนเมธอด run() วิธีนี้ถูกแนะนำมากกว่าเพราะช่วยให้โค้ดของเรายังสามารถสืบทอด (Inherit) จากคลาสอื่นได้ ทำให้การออกแบบโค้ดมีความยืดหยุ่น (Flexibility) สูงกว่า

Java

public class Task implements Runnable { 
    @Override 
    public void run() { 
        System.out.println("Thread-Runnable: กำลังทำงานด้วยข้อมูล 1,2,3..."); 
    } 
} 

// การเรียกใช้: 
// Thread t1 = new Thread(new Task()); 
// t1.start();

2. การสืบทอดจาก Thread Class

เป็นการสร้างคลาสที่สืบทอดจาก java.lang.Thread และเขียนทับเมธอด run() วิธีนี้เข้าใจง่าย แต่ข้อจำกัดคือคลาสของคุณจะถูกผูกติดกับการเป็น Thread ทำให้ไม่สามารถสืบทอดจากคลาสอื่นได้

Java

public class MyThread extends Thread { 
    @Override 
    public void run() { 
        System.out.println("Thread-Class: กำลังทำงานด้วยข้อมูล apple,banana,orange..."); 
    } 
} 

// การเรียกใช้: 
// MyThread t2 = new MyThread(); 
// t2.start();

⚠️ ข้อควรระวัง: อย่าใช้ .run() แทน .start()

นี่คือข้อผิดพลาดที่พบบ่อยที่สุด! การเรียกใช้ threadObject.run() จะทำให้โค้ดทำงานบน Main Thread ทันที ไม่ได้สร้าง Thread ใหม่ขึ้นมาอย่างแท้จริง คุณต้องใช้ threadObject.start() เสมอ เพื่อให้ระบบปฏิบัติการจัดการสร้างและรัน Thread ใหม่ใน Background

✨ บทสรุป: ก้าวสู่ระดับ Senior Architect

การเข้าใจการสร้าง Thread เป็นเพียงจุดเริ่มต้น เมื่อคุณก้าวสู่ระดับ Senior Developer คุณจะต้องให้ความสำคัญกับการจัดการทรัพยากรที่แชร์ร่วมกัน (Shared Resources) การใช้ synchronized keyword, Lock, หรือ Concurrent Collections เพื่อป้องกันปัญหา Race Condition และ Deadlock ให้ได้อย่างถูกต้อง การจัดการ Multithreading อย่างเชี่ยวชาญจึงเป็นทักษะที่สำคัญที่สุดในการสร้างระบบที่ทนทานและขยายขนาดได้จริง