2013-06-22 50 views
8

Thỉnh thoảng chúng ta buộc phải dừng một luồng như một nỗ lực tốt nhất trước khi tắt hoàn toàn toàn bộ JVM. Thông thường, Thread#stop được trích dẫn như là một cảnh báo chắc chắn, ngay cả khi bị cản trở và không dùng nữa, cách vô điều kiện dừng một luồng. Đây không phải là như vậy, tuy nhiên: tất cả các chủ đề giả mạo có phải làm gì để giữ cho bản thân chạy là bắt ThreadDeath hoặc một lớp cha:Làm thế nào để dừng vô điều kiện một sợi

public static void main(String[] args) throws InterruptedException { 
    final Thread t = new Thread() { public void run() { 
    for (;;) 
     try { Thread.sleep(Long.MAX_VALUE); } 
     catch (Throwable t) { 
     System.out.println(t.getClass().getSimpleName() + ". Still going on..."); 
     } 
    }}; 
    t.start(); 
    Thread.sleep(200); 
    t.interrupt(); 
    Thread.sleep(200); 
    t.interrupt(); 
    Thread.sleep(200); 
    t.stop(); 
    Thread.sleep(200); 
    t.stop(); 
} 

này sẽ in

InterruptedException. Still going on... 
InterruptedException. Still going on... 
ThreadDeath. Still going on... 
ThreadDeath. Still going on... 

Có điều gì khác mà tôi có thể làm để thực sự, thực sự ngăn chặn một chủ đề mà không giết chết toàn bộ JVM?

+2

Tôi biết nó không trả lời câu hỏi [nhưng đây là một đọc tốt về chủ đề] (http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation. html), nó giải thích lý do tại sao dừng lại không được chấp nhận ở nơi đầu tiên. Ngoài ra, tại sao bạn sẽ có một 'rouge thread' có thể bắt được TheadDeath và bị gián đoạn ngay từ đầu? Chủ đề không có nghĩa là cho điều đó. Họ không cung cấp bảo mật. Các chủ đề khác cũng có thể chấm dứt chính JVM - hoặc sinh ra các luồng có vấn đề khác. –

+0

Đây có lẽ là một câu hỏi học thuật; Tôi chỉ muốn biết chính xác những gì từng kỹ thuật dừng lại và những kỹ thuật nào có ở nơi đầu tiên. Như một nhu cầu cụ thể thể hiện bản thân, loại kiến ​​thức này là những gì có thể giúp bạn tiết kiệm. –

+0

@BenjaminGruenbaum Tôi khuyên bạn nên gửi một câu trả lời đơn giản là "không": không có cách nào để thực sự, _really_ (buộc) dừng một chuỗi mà không giết toàn bộ JVM, và sau đó liên kết đến bài viết đó. –

Trả lời

5

Không. Không có cách nào được xây dựng theo cách đơn giản để thực sự dừng một chuỗi.

như một phương pháp, tiêu diệt was planned but not implemented:

Deprecated. Phương pháp này ban đầu được thiết kế để tiêu diệt luồng này mà không cần dọn dẹp. Bất kỳ màn hình nào được giữ sẽ vẫn bị khóa. Tuy nhiên, phương pháp này chưa bao giờ được thực hiện. Nếu nếu được triển khai, nó sẽ dễ bị bế tắc theo cách thức đình chỉ(). Nếu chuỗi đích giữ một khóa bảo vệ tài nguyên hệ thống quan trọng khi nó bị phá hủy, không có luồng nào có thể truy cập lại tài nguyên này nữa. Nếu một luồng khác đã từng cố khóa tài nguyên này, bế tắc sẽ dẫn đến kết quả. Những deadlocks như vậy thường biểu hiện các quá trình "đông lạnh".

Chủ đề không có ý nghĩa như vậy. Họ không cung cấp bảo mật. Các chủ đề khác cũng có thể chấm dứt chính JVM - hoặc sinh ra các luồng có vấn đề khác.

Để biết thêm thông tin, see Why are Thread.stop, Thread.suspend and Thread.resume không còn được dùng nữa. Bạn có thể read why here.

+0

Các đối số nghỉ ngơi trên không thực hiện 'phá hủy' là một tốt; đối với các nhận xét khác về tài sản thế chấp, chúng không đặc biệt nổi bật bởi vì 1. chúng đã là kiến ​​thức phổ biến kể từ ít nhất là ngày 1,4 và 2. bởi vì một lập trình viên có trách nhiệm vẫn có thể muốn giết một chuỗi được nhắm mục tiêu cụ thể. không được tắt bất kỳ trạng thái được chia sẻ nào hoặc giữ bất kỳ tài nguyên bên ngoài nào. –

+0

Trích dẫn tham khảo của bạn: "Chúng tôi hiện không thực hiện [' Phá hủy chủ đề '] vào lúc này, nhưng chúng tôi cũng không từ chối nó (thực hiện việc triển khai nó trong tương lai) trong khi nó chắc chắn là bế tắc, nó đã được lập luận rằng có thể là hoàn cảnh mà một chương trình sẵn sàng mạo hiểm bế tắc thay vì thoát hoàn toàn. " –

+0

Một điểm khác: một luồng có thể được ngăn chặn mạnh mẽ khỏi việc chấm dứt JVM, bằng cách cài đặt một 'SecurityManager'. –

0

Không có cách nào để đảm bảo rằng chuỗi đó có thể dừng lại trong Java. Cách hiệu quả nhất là Thread.stop nhưng đó là một tai nạn đang chờ xảy ra. Các lựa chọn thay thế là sử dụng Thread.interrupt và có chủ đề kiểm tra cờ nhưng cả hai đều dựa vào chuỗi được mã hóa chính xác và, trong trường hợp cờ, kiểm tra nó một cách thường xuyên.

Cá nhân, tôi sẽ đảm bảo rằng tôi không bắt được ThreadDeath. Stop là một cách không tốt để ngăn chặn một luồng nhưng ít nhất bạn sẽ nhận được một thông báo miễn là bạn không bắt ThreadDeath.

+0

Tôi chưa bao giờ bắt được 'ThreadDeath', nhưng tôi thường xuyên bắt được' Throwable' vì tôi thường muốn biết rằng một thường trình đang hoàn thành đột ngột vì bất kỳ lý do gì, và cũng để duy trì một vòng lặp cấp cao nhất. –

+0

Marko, nếu mã thực sự bắt Throwable và chỉ tiếp tục đi, không bao giờ kiểm tra bị gián đoạn (hoặc một lá cờ), thì đó là lỗi của mã, chứ không phải của Java. – user949300

+0

@ user949300 Một khi bạn có mã nước ngoài hành xử xấu trong dự án của bạn, nó sẽ có chút an ủi để tìm ra nó không phải là lỗi của Java. –

Các vấn đề liên quan