Java Threads
Java Threads
เธรดช่วยให้โปรแกรมทำงานได้อย่างมีประสิทธิภาพมากขึ้นโดยทำหลายๆ อย่างพร้อมกัน
สามารถใช้เธรดเพื่อทำงานที่ซับซ้อนในพื้นหลังโดยไม่ขัดจังหวะโปรแกรมหลัก
การสร้างกระทู้
มีสองวิธีในการสร้างเธรด
สามารถสร้างได้โดยการขยายThread
คลาสและแทนที่run()
วิธีการ:
ขยายไวยากรณ์
public class Main extends Thread { public void run() { System.out.println("This code is running in a thread");
}}
อีกวิธีหนึ่งในการสร้างเธรดคือการใช้Runnable
อินเทอร์เฟซ:
ใช้ไวยากรณ์
public class Main implements Runnable {
public void run() {
System.out.println("This code is running in a thread");
}
}
วิ่งกระทู้
หากคลาสขยายThread
คลาส เธรดสามารถรันได้โดยการสร้างอินสแตนซ์ของคลาสและเรียกใช้start()
เมธอด:
ขยายตัวอย่าง
public class Main extends Thread {
public static void main(String[] args) {
Main thread = new Main();
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
หากคลาสใช้Runnable
อินเทอร์เฟซ สามารถเรียกใช้เธรดโดยส่งอินสแตนซ์ของคลาสไปยังตัวสร้างThread
ของอ็อบเจ็กต์แล้วเรียกใช้
start()
เมธอดของเธรด:
ใช้ตัวอย่าง
public class Main implements Runnable {
public static void main(String[] args) {
Main obj = new Main();
Thread thread = new Thread(obj);
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
ความแตกต่างระหว่างเธรด "การขยาย" และ "การใช้งาน"
ความแตกต่างที่สำคัญคือเมื่อคลาสขยายคลาส Thread คุณจะไม่สามารถขยายคลาสอื่นได้ แต่ด้วยการใช้อินเทอร์เฟซ Runnable เป็นไปได้ที่จะขยายจากคลาสอื่นเช่นกัน เช่น: MyClass extends OtherClass implements Runnable
class
ปัญหาการทำงานพร้อมกัน
เนื่องจากเธรดทำงานพร้อมกันกับส่วนอื่น ๆ ของโปรแกรม จึงไม่มีทางทราบได้ว่าโค้ดจะทำงานในลำดับใด เมื่อเธรดและโปรแกรมหลักกำลังอ่านและเขียนตัวแปรเดียวกัน ค่าต่างๆ จะคาดเดาไม่ได้ ปัญหาที่เกิดจากสิ่งนี้เรียกว่าปัญหาที่เกิดขึ้นพร้อมกัน
ตัวอย่าง
ตัวอย่างโค้ดที่ค่าของจำนวน ตัวแปร ไม่สามารถคาดเดาได้:
public class Main extends Thread { public static int amount = 0; public static void main(String[] args) { Main thread = new Main(); thread.start(); System.out.println(amount); amount++; System.out.println(amount);
}public void run() { amount++;
}}
เพื่อหลีกเลี่ยงปัญหาการทำงานพร้อมกัน เป็นการดีที่สุดที่จะแบ่งปันแอตทริบิวต์ระหว่างเธรดให้น้อยที่สุด หากจำเป็นต้องแชร์แอตทริบิวต์ วิธีแก้ปัญหาหนึ่งที่เป็นไปได้คือใช้isAlive()
วิธีการของเธรดเพื่อตรวจสอบว่าเธรดทำงานเสร็จแล้วหรือไม่ก่อนที่จะใช้แอตทริบิวต์ใดๆ ที่เธรดสามารถเปลี่ยนแปลงได้
ตัวอย่าง
ใช้isAlive()
เพื่อป้องกันปัญหาการทำงานพร้อมกัน:
public class Main extends Thread { public static int amount = 0; public static void main(String[] args) { Main thread = new Main(); thread.start(); // Wait for the thread to finish while(thread.isAlive()) { System.out.println("Waiting...");
}// Update amount and print its value System.out.println("Main: " + amount); amount++; System.out.println("Main: " + amount);
}public void run() { amount++;
}}