(Post 16/10/2007) Tuy nhiên, việc tự ý ngắt một chuỗi là rất nguy hiểm, vì bất kỳ khung công tác hoặc phương thức của bên thứ ba nào trong ngăn xếp gọi có thể nhận được ngắt một cách bất ngờ thay vì mã dự định của bạn. Tất cả những gì cần làm là luồng có thể chặn trong thời gian ngắn trên một tài nguyên khóa hoặc đồng bộ hóa đơn giản và bất kỳ sự gián đoạn nào đang chờ xử lý sẽ bắt đầu. ở trạng thái không sử dụng được hoặc tài nguyên được giải phóng không đầy đủ.
- Phần 1: Tổng quan và khái niệm
- Phần 2: Tạo và bắt đầu chủ đề
- Phần 3: Cơ bản về đồng bộ hóa
- Phần 4: Khóa và an toàn chỉ
Một chuỗi bị chặn có thể được giải phóng sớm theo một trong hai cách:
- thông qua Thread.Interrupt
- qua Thread.Abort
Điều này phải xảy ra thông qua các hoạt động của một luồng khác; luồng chờ bất lực để làm bất cứ điều gì trong trạng thái bị chặn của nó.
Làm gián đoạn
Gọi Ngắt trên một chuỗi bị chặn buộc giải phóng nó, ném ra một ThreadInterruptException, như sau:
class Program {
static void Main () {
Thread t = new Thread (Delegate () {
try {
Thread.Sleep (Timeout.Infinite);
}
catch (ThreadInterruptException) {
Console.Write (“Forcibly”);
}
Console.WriteLine ( “Đã tỉnh!”);
});
t.Start ();
t.Interrupt ();
}
}
Bị đánh thức cưỡng bức! |
Việc ngắt một luồng chỉ giải phóng nó khỏi thời gian chờ hiện tại (hoặc tiếp theo): nó không khiến luồng kết thúc (tất nhiên, trừ khi, ThreadInterruptException không được xử lý!)
Nếu Interrupt được gọi trên một luồng không bị chặn, thì luồng tiếp tục thực thi cho đến khi nó chặn tiếp theo, lúc này một ThreadInterruptException được ném ra. Điều này tránh sự cần thiết phải kiểm tra sau:
if ((worker.ThreadState & ThreadState.WaitSleepJoin)> 0)
worker.Interrupt ();
không an toàn cho luồng vì có khả năng bị lấn át giữa câu lệnh if và worker.Interrupt.
Tuy nhiên, việc ngắt một luồng một cách tùy tiện là rất nguy hiểm vì bất kỳ khung công tác hoặc phương thức của bên thứ ba nào trong ngăn xếp gọi có thể bất ngờ nhận được ngắt chứ không phải mã dự định của bạn. Tất cả những gì cần làm là luồng có thể chặn trong thời gian ngắn trên một tài nguyên khóa hoặc đồng bộ hóa đơn giản và bất kỳ sự gián đoạn nào đang chờ xử lý sẽ bắt đầu. ở trạng thái không sử dụng được hoặc tài nguyên được giải phóng không đầy đủ.
Việc ngắt một luồng sẽ an toàn khi bạn biết chính xác vị trí của luồng đó. Sau đó, chúng tôi đề cập đến các cấu trúc báo hiệu , chúng chỉ cung cấp một phương tiện như vậy.
Huỷ bỏ
Một luồng bị chặn cũng có thể được giải phóng cưỡng bức thông qua phương thức Abort của nó. Điều này có tác dụng tương tự như việc gọi Interrupt, ngoại trừ việc một ThreadAbortException được ném thay vì ThreadInterruptException. Hơn nữa, ngoại lệ sẽ được ném lại vào cuối khối catch (trong nỗ lực kết thúc chuỗi cho tốt) trừ khi Thread.ResetAbort được gọi trong khối catch. Trong thời gian tạm thời, luồng có ThreadState của AbortRequested.
Tuy nhiên, sự khác biệt lớn giữa Interrupt và Abort là những gì sẽ xảy ra khi nó được gọi trên một luồng không bị chặn. Trong khi Interrupt đợi cho đến khi luồng tiếp theo chặn trước khi thực hiện bất cứ điều gì, Abort ném một ngoại lệ trên luồng ngay nơi nó đang thực thi – thậm chí có thể không có trong mã của bạn. Việc hủy bỏ một chuỗi không bị chặn có thể gây ra những hậu quả đáng kể, chi tiết về chúng sẽ được khám phá trong phần sau “Hủy chuỗi” .
(Sưu tầm)
FPT Aptech – Hệ Thống Đào Tạo Lập Trình Viên Quốc Tế
FPT Aptech trực thuộc Tổ chức Giáo dục FPT có hơn 25 năm kinh nghiệm đào tạo lập trình viên quốc tế tại Việt Nam, và luôn là sự lựa chọn ưu tiên của các sinh viên và nhà tuyển dụng. |