Chủ đề Java
Chủ đề Java
Chủ đề cho phép chương trình hoạt động hiệu quả hơn bằng cách thực hiện nhiều việc cùng một lúc.
Các luồng có thể được sử dụng để thực hiện các tác vụ phức tạp ở chế độ nền mà không làm gián đoạn chương trình chính.
Tạo một chủ đề
Có hai cách để tạo một chủ đề.
Nó có thể được tạo bằng cách mở rộng lớp Thread
và ghi đè phương thức run()
của nó:
Cú pháp mở rộng
public class Main extends Thread { public void run() { System.out.println("This code is running in a thread");
}}
Một cách khác để tạo một luồng là triển khai giao diện Runnable
:
Thực hiện cú pháp
public class Main implements Runnable { public void run() { System.out.println("This code is running in a thread"); } }
Chạy chủ đề
Nếu lớp mở rộng lớp Thread
, luồng có thể được chạy bằng cách tạo một thể hiện của lớp và gọi phương thức start()
của nó:
Mở rộng ví dụ
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"); } }
Nếu lớp triển khai giao diện Runnable
, luồng có thể được chạy bằng cách chuyển một thể hiện của lớp tới hàm tạo của đối tượng Thread
và sau đó gọi phương thức start()
của luồng:
Triển khai ví dụ
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"); } }
Sự khác biệt giữa Chủ đề "mở rộng" và "triển khai"
Sự khác biệt chính là khi một lớp mở rộng lớp Thread, bạn không thể mở rộng bất kỳ lớp nào khác, nhưng bằng cách triển khai giao diện Runnable, bạn cũng có thể mở rộng từ một lớp khác, như: class MyClass extends OtherClass implements Runnable
.
Vấn đề đồng thời
Vì các luồng chạy cùng lúc với các phần khác của chương trình nên không có cách nào để biết mã sẽ chạy theo thứ tự nào. Khi các luồng và chương trình chính đọc và ghi cùng một biến, các giá trị sẽ không thể đoán trước được. Các vấn đề phát sinh từ việc này được gọi là các vấn đề tương tranh.
Ví dụ
Một ví dụ mã trong đó giá trị của biến money là không thể dự đoán được:
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++;
}}
Để tránh các vấn đề tương tranh, tốt nhất nên chia sẻ càng ít thuộc tính giữa các luồng càng tốt. Nếu các thuộc tính cần được chia sẻ, một giải pháp khả thi là sử dụng phương thức isAlive()
của luồng để kiểm tra xem luồng đã chạy xong hay chưa trước khi sử dụng bất kỳ thuộc tính nào mà luồng có thể thay đổi.
Ví dụ
Sử dụng isAlive()
để ngăn chặn các vấn đề tương tranh:
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++;
}}