ในโลกของการพัฒนาซอฟต์แวร์ยุคใหม่ ความเร็วและการตอบสนองเป็นปัจจัยชี้ขาดความสำเร็จของระบบ การที่แอปพลิเคชันต้องจัดการกับงานหลายอย่างพร้อมกัน ไม่ว่าจะเป็นการรับคำขอจากผู้ใช้จำนวนมาก (High Concurrency) หรือการประมวลผลข้อมูลขนาดใหญ่ในเวลาจำกัด ทำให้แนวคิดเรื่อง Parallelism และ Concurrency กลายเป็นหัวใจสำคัญของการออกแบบสถาปัตยกรรมระบบที่แข็งแกร่งและมีประสิทธิภาพ
เจาะลึกรายละเอียดและประเด็นสำคัญ
การทำความเข้าใจกลไกของ Multithreading ใน Java เริ่มต้นจากการแยกแยะระหว่าง Process และ Thread โดยที่ Thread คือหน่วยของการทำงานที่เบากว่า (Lightweight) ซึ่งช่วยให้เราสามารถรันงานหลายอย่างในกระบวนการเดียวกันได้พร้อมกัน แนวคิดหลักคือการใช้ `Runnable` Interface เพื่อกำหนด Task ที่ต้องการให้ถูกดำเนินการโดย Thread แยกต่างหาก การจัดการด้วยตัวเองอาจนำไปสู่ปัญหา Deadlock หรือ Race Condition ได้ง่าย
เพื่อแก้ไขข้อบกพร่องเหล่านี้ Java จึงได้พัฒนาเครื่องมือระดับสูงอย่าง `ExecutorService` ซึ่งเป็น Best Practice ในการบริหารจัดการ Thread Pool ทำให้เราไม่ต้องยุ่งเกี่ยวกับการสร้างและปิด Thread ด้วยตนเอง นอกจากนี้ การควบคุมการเข้าถึงทรัพยากรที่ใช้ร่วมกัน (Shared Resources) ต้องอาศัยคีย์เวิร์ดสำคัญ เช่น synchronized เพื่อรับประกัน Mutual Exclusion และ volatile เพื่อให้มั่นใจในเรื่อง Visibility ของตัวแปร
Plain Text
<pre class="wp-block-syntaxhighlighter-code">import java.util.concurrent.*;
public class ConcurrencyDemo {
public static void main(String[] args) throws InterruptedException {
// 1. การใช้ ExecutorService เพื่อจัดการ Thread Pool
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 3; i++) {
final int taskId = i;
executor.submit(() -> {
// 2. การจำลองงานที่ต้องใช้ทรัพยากรร่วมกัน
synchronized (ConcurrencyDemo.class) {
System.out.println("Task " + taskId + " is running on thread: " + Thread.currentThread().getName());
try {
Thread.sleep(100); // จำลองการทำงาน I/O bound
} catch (InterruptedException e) {}
}
});
}
executor.shutdown(); // ปิด Pool อย่างถูกต้อง
}
}