Trong Java, một Thread
đại diện cho một luồng thực thi độc lập trong chương trình, cho phép thực hiện nhiều công việc đồng thời (multithreading). Java cung cấp nhiều cách khác nhau để tạo một Thread
, mỗi cách đều có các ưu điểm riêng biệt. Trong bài viết này, chúng ta sẽ xem xét các cách tạo một Thread
và thảo luận về sự khác biệt giữa chúng. Cuối cùng, tôi sẽ chia sẻ quan điểm về cách tạo Thread
mà tôi thích và lý do tại sao.
Thread
Cách đơn giản nhất để tạo một Thread
là kế thừa từ lớp Thread
và ghi đè phương thức run()
để định nghĩa hành vi của thread. Sau đó, bạn có thể tạo một đối tượng của lớp con và gọi phương thức start()
để bắt đầu luồng thực thi.
class MyThread extends Thread { @Override public void run() { System.out.println("Thread is running"); } } MyThread thread = new MyThread(); thread.start();
Trong ví dụ trên, chúng ta tạo lớp MyThread
kế thừa từ Thread
và định nghĩa hành vi trong phương thức run()
. Phương thức start()
được gọi để bắt đầu thực thi thread.
Ưu điểm:
Thread
như sleep()
, join()
, interrupt()
.Nhược điểm:
Thread
.Runnable
Một cách khác để tạo Thread
là triển khai giao diện Runnable
. Bạn sẽ cần cung cấp định nghĩa cho phương thức run()
và truyền một đối tượng Runnable
vào đối tượng Thread
để thực thi luồng.
class MyRunnable implements Runnable { @Override public void run() { System.out.println("Thread is running"); } } Thread thread = new Thread(new MyRunnable()); thread.start();
Trong ví dụ này, chúng ta tạo lớp MyRunnable
triển khai giao diện Runnable
và định nghĩa hành vi trong phương thức run()
. Sau đó, chúng ta truyền đối tượng MyRunnable
vào lớp Thread
và gọi phương thức start()
.
Ưu điểm:
Runnable
.Nhược điểm:
Thread
, nên phải sử dụng đối tượng Thread
để khởi chạy thread.Từ Java 8, với sự ra đời của biểu thức lambda, bạn có thể tạo Thread
một cách gọn gàng hơn khi triển khai giao diện Runnable
. Thay vì định nghĩa một lớp riêng biệt, bạn có thể truyền trực tiếp một biểu thức lambda vào Thread
.
Thread thread = new Thread(() -> { System.out.println("Thread is running"); }); thread.start();
Biểu thức lambda cho phép bạn tạo Thread
một cách ngắn gọn và trực quan hơn, đặc biệt là trong những tình huống đơn giản.
Ưu điểm:
Runnable
truyền thống.Nhược điểm:
Callable
và Future
Nếu bạn cần kết quả trả về từ thread hoặc cần xử lý ngoại lệ, giao diện Callable
là lựa chọn tốt hơn so với Runnable
. Callable
cho phép trả về kết quả và ném ngoại lệ. Sau đó, bạn có thể sử dụng ExecutorService
để quản lý thread và lấy kết quả bằng Future
.
import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; class MyCallable implements Callable<String> { @Override public String call() throws Exception { return "Thread result"; } } ExecutorService executor = Executors.newSingleThreadExecutor(); Future<String> future = executor.submit(new MyCallable()); String result = future.get(); // Lấy kết quả từ thread System.out.println(result); executor.shutdown();
Ở đây, Callable
giúp bạn trả về kết quả từ thread thông qua Future
. Phương thức call()
thay thế run()
trong Runnable
và có thể ném ngoại lệ.
Ưu điểm:
Nhược điểm:
Runnable
trong việc quản lý thread.ExecutorService
và Future
.Cách tôi thích nhất để tạo Thread
trong Java là triển khai giao diện Runnable
.
Runnable
cho phép tôi tách biệt hành vi của thread khỏi lớp cụ thể, giúp mã nguồn dễ tái sử dụng hơn. Ngoài ra, tôi có thể kế thừa từ các lớp khác nếu cần, mà không bị giới hạn bởi việc chỉ có thể kế thừa một lớp trong Java.Runnable
giúp tôi và đồng đội dễ dàng theo dõi và duy trì mã nguồn hơn, đặc biệt khi xử lý các logic phức tạp trong thread.Runnable
có tính tương thích cao, dễ sử dụng và dễ kết hợp với các framework hoặc API khác trong Java. Điều này giúp tôi linh hoạt hơn khi cần tích hợp với các công cụ quản lý thread khác như ExecutorService
.Tóm lại, Java cung cấp nhiều cách để tạo Thread
, bao gồm kế thừa từ Thread
, triển khai Runnable
, sử dụng lambda, và Callable
với Future
. Cá nhân tôi ưa thích sử dụng Runnable
vì tính linh hoạt, khả năng tái sử dụng, và tính rõ ràng mà nó mang lại trong việc phát triển phần mềm.