2010-12-15 23 views
5
package util.concurrent; 

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class ShutdownDemo { 
public static void main(String[] args) throws InterruptedException{ 
    ExecutorService executor = Executors.newSingleThreadExecutor(); 

    executor.execute(new Runnable(){ 

    @Override 
    public void run() { 
    while(true){ 
    System.out.println("-- test --"); 
    } 
    } 

    }); 

    TimeUnit.SECONDS.sleep(3); 

    executor.shutdownNow(); 
} 
} 

Tôi đã viện dẫn phương thức shutdownNow, tại sao bàn điều khiển tiếp tục in "- test -" ??Tại sao ExecutorService.shutdownNow method không thể dừng thread

Trả lời

1

Từ JavaDocs, các ExecutorService # shutdownNow phương pháp không được bảo đảm để thực sự dừng các công việc thực hiện. Bạn đang tốt hơn nhiều tắt đột biến một số biến trạng thái mà các công việc lâu dài sẽ định kỳ kiểm tra và phát hiện sự thay đổi, bỏ vòng lặp chạy của họ.

+1

Điều này được phóng đại. Biến trạng thái của bạn không khác với biến trạng thái đã được cung cấp bởi Thread.interrupted. Nó sẽ hành xử theo cùng một cách chính xác. Trong khi bạn có thể viết mã mà sẽ đảm bảo một shutdownNow() sẽ không hoàn thành - đó là lỗi của tác giả - nếu bạn làm theo các quy tắc tôi tuyên bố nó sẽ tắt máy cuối cùng. Các cuộc gọi mạng cuối cùng hết thời gian chờ, nhưng trong khi thời gian đó không hết hạn, luồng sẽ phải chờ cho đến khi hết thời gian chờ. Điều này cũng đúng cho một biến trạng thái chia sẻ. – chubbsondubs

10

Check-out Thread.stop() trong javadoc cho lý do đầy đủ:

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#stop()

Về cơ bản, chủ đề của bạn phải dừng lại trên riêng của nó để cho chương trình của bạn để giữ an toàn. Chỉ cần dừng một luồng có thể để lại các chương trình ở trạng thái không thể đoán trước khi các khóa thuộc sở hữu của luồng không được giải phóng và các tài nguyên không được trả lại cho hệ điều hành. Cuối cùng rời khỏi chương trình của bạn để mở khóa chết, rò rỉ bộ nhớ mà không thể được giải phóng, và có khả năng ảnh hưởng đến sự ổn định của hệ điều hành là tốt quá. Điều này thực sự không phải là bất kỳ khác nhau nếu bạn đang ở trong C hoặc bất kỳ ngôn ngữ khác bởi vì dừng chủ đề bản địa có những vấn đề này. Hãy nhớ rằng các luồng không phải là các tiến trình mà chúng chia sẻ bộ nhớ và trạng thái với các luồng khác để chúng phải hoạt động và hợp tác.

Java hoạt động trên các chuỗi bị gián đoạn trái ngược với việc hủy chuỗi để đề phải phù hợp với mô hình này khi bạn viết chúng. Vì vậy, trong khi (đúng) trong chương trình của bạn là thực hành xấu. Thay vào đó, bạn cần phải xem liệu chuỗi của bạn có bị gián đoạn hay không và tự tắt máy. Hoặc với Thread.sleep và xử lý InterruptedException đúng cách. Hoặc kiểm tra Thread.isInterrupted() trong vòng lặp while của bạn.

+0

Nhưng đây là một thể hiện của 'Runnable' - nơi chúng ta có thể nhận được tại' Thread.isInterrupted() '? Ngoài ra, nếu 'shutdownNow()' cố gắng ngắt thread của chúng ta trong khi nó không ngủ nó sẽ chỉ thiết lập cờ bị gián đoạn và sẽ không tạo ra 'InterruptedException' khi chúng ta' sleep() 'một lần nữa (nếu tôi hiểu tài liệu đúng). – drevicko

+1

Bạn luôn có thể nhận được chuỗi thực hiện bất kỳ phần nào của mã đó bằng cách sử dụng Thread.currentThread(). IsInterrupted(). Hãy nhớ một khi một luồng bị gián đoạn bất kỳ sleep() hoặc wait() nào sẽ tạo ra một InterruptedException. – chubbsondubs

+0

Cool, cảm ơn (: Chỉ cần chắc chắn rằng tôi đã hiểu đúng, nếu thread của chúng ta 'interrupt()' được gọi và chúng ta không ngủ() ing, sau đó chúng ta 'sleep()' cho một chút, một ' InterruptedException' được tạo ngay lập tức? Có lẽ đây là một phần của đặc tả Java và nên được thực hiện trong tất cả các thư viện chuẩn của VM/ – drevicko

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