Java - Ngắt luồng Thread

Xin chào các nhà phát triển Java tương lai! Hôm nay, chúng ta sẽ vào thế giới đầy kỳ lạ của việc ngắt luồng trong Java. Đừng lo nếu bạn mới bắt đầu học lập trình; tôi sẽ hướng dẫn bạn từng bước trên hành trình này, như thế tôi đã làm cho nhiều học viên khác trong những năm dạy học. Vậy hãy lấy ly đồ uống yêu thích của bạn, thoải mái ngồi, và hãy cùng nhau bắt đầu cuộc phiêu lưu này!

Java - Interrupting a Thread

Luồng INTERRUPTION là gì?

Trước khi bước vào chi tiết, hãy hiểu rõ về việc ngắt luồng là gì. Hãy tưởng tượng bạn đang đọc một cuốn sách dài (gọi nó là "The Epic Java Saga"), và đột ngột bạn bè của bạn gọi điện thoại mời bạn đến bữa tiệc pizza khẩn cấp. Bạn cần phải dừng đọc ngay lập tức và đi. Đó chính là điều gì việc ngắt luồng trong thế giới lập trình - cách thân thiện để nói với luồng, "Hey bạn, thời gian để kết thúc việc này!"

Tại sao chúng ta cần ngắt luồng?

Bạn có thể hỏi, "Tại sao chúng ta không để luồng làm việc của mình?" Đúng là, các bạn yêu quý, đôi khi trong thế giới phức tạp của đa luồng, chúng ta cần ngắt một luồng vì nhiều lý do khác nhau:

  1. Nhiệm vụ không còn cần thiết nữa (như hủy tải xuống)
  2. Ứng dụng đang tắt
  3. Để tránh chi tiêu tài nguyên

Các phương thức để ngắt luồng

Bây giờ, hãy xem các công cụ mà Java cung cấp để ngắt luồng. Hãy nghĩ về chúng như là "công thức ma thuật" để kiểm soát luồng.

Phương thức Mô tả
interrupt() Ngắt luồng
isInterrupted() Kiểm tra nếu luồng đã bị ngắt
Thread.interrupted() Kiểm tra nếu luồng hiện tại đã bị ngắt và xóa trạng thái bị ngắt

Ví dụ về việc ngắt luồng Java

Bắt đầu với một ví dụ đơn giản. Chúng ta sẽ tạo một luồng đếm cừu (vì ai mà không yêu thích việc đếm cừu?), và sau đó chúng ta sẽ ngắt nó.

public class SheepCounter implements Runnable {
@Override
public void run() {
try {
for (int i = 1; i <= 100; i++) {
System.out.println("Đếm cừu: " + i);
Thread.sleep(1000); // Ngủ 1 giây
}
} catch (InterruptedException e) {
System.out.println("Việc đếm cừu bị ngắt! Thời gian để thức dậy!");
}
}

public static void main(String[] args) throws InterruptedException {
Thread sheepThread = new Thread(new SheepCounter());
sheepThread.start();

// Đếm cừu trong 5 giây
Thread.sleep(5000);

// Thời gian để thức dậy!
sheepThread.interrupt();
}
}

Trong ví dụ này, chúng ta tạo một SheepCounter đếm đến 100 cừu, nghỉ 1 giây giữa mỗi lần đếm. Trong phương thức main, chúng ta bắt đầu luồng đếm cừu, để nó chạy trong 5 giây, và sau đó ngắt nó.

Khi bạn chạy đoạn mã này, bạn sẽ thấy việc đếm cừu bắt đầu, và sau khoảng 5 cừu, nó sẽ bị ngắt. Như thế là ai đó bật đèn trong khi bạn đang cố gắng ngủ.

Xử lý InterruptedException

Bây giờ, hãy xem một ví dụ phức tạp hơn nơi chúng ta xử lý InterruptedException một cách trân trọng.

public class PoliteWorker implements Runnable {
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Đang làm việc chăm chỉ...");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Bị ngắt! Đang dọn dẹp...");
} finally {
System.out.println("Việc hoàn thành!");
}
}

public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(new PoliteWorker());
worker.start();

// Để công nhân làm việc trong 5 giây
Thread.sleep(5000);

// Thời gian để về nhà!
worker.interrupt();
}
}

Trong ví dụ này, PoliteWorker kiểm tra nếu nó đã bị ngắt trước mỗi chu kỳ làm việc. Nếu nó bị ngắt trong khi ngủ, nó sẽ bắt ngoại lệ InterruptedException, làm sạch và thoát một cách trân trọng. Như một nhân viên tốt đẹp nằm dọn dẹp bàn trước khi về nhà!

Kiểm tra xem luồng có bị ngắt không

Đôi khi, bạn có thể muốn kiểm tra nếu luồng đã bị ngắt mà không ném ngoại lệ. Dưới đây là cách bạn có thể làm điều đó:

public class InterruptChecker implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Tôi đã bị ngắt! Thoát...");
return;
}
System.out.println("Đang làm việc... " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Ngủ bị ngắt! Thoát...");
return;
}
}
}

public static void main(String[] args) throws InterruptedException {
Thread checker = new Thread(new InterruptChecker());
checker.start();

// Để nó làm việc trong 3 giây
Thread.sleep(3000);

// Ngắt!
checker.interrupt();
}
}

Trong ví dụ này, chúng ta sử dụng isInterrupted() để kiểm tra nếu luồng đã bị ngắt. Như một công nhân đôi khi nhìn vào đồng hồ để xem có thời gian để về nhà hay không.

Kết luận

Và thế là xong, các bạn yêu quý! Chúng ta đã hành trình qua thế giới ngắt luồng trong Java. Hãy nhớ, việc ngắt luồng như là một quản lý tốt - bạn cần phải giao tiếp rõ ràng và đưa luồng cơ hội để dọn dẹp sau mình.

Khi bạn tiếp tục hành trình Java của mình, bạn sẽ thấy rằng việc kiểm soát ngắt luồng là rất quan trọng để tạo ra các ứng dụng đa luồng phản hồi nhanh và hiệu quả. Đây là kỹ năng sẽ phục vụ bạn tốt, không chỉ khi bạn xây dựng nền tảng mạng xã hội lớn nhất mà còn khi bạn chỉ cố gắng đếm cừu một cách hiệu quả hơn!

Hãy tiếp tục tập luyện, duy trì sự tò mò, và nhất định là hãy vui vẻ với Java! Ai biết? Có lẽ một ngày nào đó bạn sẽ là người dạy khác về niềm vui của việc ngắt luồng. Đến lần sau, hạnh phúc với lập trình!

Credits: Image by storyset