2010-01-06 7 views
8

Các chương trình sau đây chứng tỏ vấn đề (mới nhất JVM & không có điều gì):Thread.isInterrupted không hoạt động, Thread.interrupted không

public static void main(String[] args) throws InterruptedException { 
    // if this is true, both interrupted and isInterrupted work 
    final boolean withPrint = false; 

    // decide whether to use isInterrupted or interrupted. 
    // if this is true, the program never terminates. 
    final boolean useIsInterrupted = true; 

    ExecutorService executor = Executors.newSingleThreadExecutor(); 
    final CountDownLatch latch = new CountDownLatch(1); 
    Callable<Void> callable = new Callable<Void>() { 
     @Override 
     public Void call() throws Exception { 
      Random random = new Random(); 
      while (true) { 
       if (withPrint) { 
        System.out.println(random.nextInt()); 
        System.out.flush(); 
       } 
       if (useIsInterrupted) 
       { 
        if (Thread.currentThread().isInterrupted()) 
         break; 
       } 
       else 
       { 
        if (Thread.interrupted()) 
         break; 
       } 
      } 
      System.out.println("Nice shutdown"); 
      latch.countDown(); 
      return null; 
     } 
    }; 
    System.out.println("Task submitted"); 
    Future<Void> task = executor.submit(callable); 
    Thread.sleep(100); 
    task.cancel(true); 
    latch.await(); 
    System.out.println("Main exited"); 
    executor.shutdown(); 
} 
+0

Nó không * luôn * không dừng lại. – Jerome

+0

Trên máy của tôi nó. – ripper234

+0

jerome, kiểm tra cài đặt trình biên dịch của bạn ... có thể bạn đang sử dụng JVM cũ hơn. – PaulP1975

Trả lời

4

này trông giống như một known issue với máy đa xử lý, chủ yếu là ở hệ điều hành và java phiên bản 64-bit 1,5-7,0

một mô tả về các vấn đề: Trong khi chạy hai luồng đồng thời, thread đầu tiên làm gián đoạn thứ hai sử dụng Thread.interrupt(). Thử nghiệm luồng thứ hai nếu nó bị gián đoạn, gọi phương thức Thread.isInterrupted() luôn trả về false.

Điều này xảy ra trên PC đa xử lý chạy hệ điều hành 64 bit (Vista và Linux). Trên Vista 64-Bit, điều này xảy ra khi sử dụng một JVM 64 bit (tất cả các phiên bản từ 1.5 đến 1.7), nhưng không xảy ra khi sử dụng một JVM 32 bit. Trên Linux 64 bit, điều này xảy ra khi sử dụng JVM 64 bit (tất cả các phiên bản 1,5 đến 1,7) hoặc khi sử dụng JVM 32 bit (tất cả các phiên bản 1,5 đến 1,7).

Giải pháp là cài đặt phiên bản có bản sửa lỗi, là 1.6.0_16-b02 trở lên.

+0

Đẹp bắt, nhưng tình trạng của lỗi là "giải quyết cố định trong hs16 (b04)". Đây là phiên bản tôi đang chạy: phiên bản java "1.6.0_14" Môi trường chạy thử Java (TM) SE (xây dựng 1.6.0_14-b08) Java HotSpot (TM) Máy chủ 64-bit VM (xây dựng 14.0-b16 , chế độ hỗn hợp) – ripper234

+0

Hoặc có lẽ tôi chỉ không hiểu số phiên bản java. Có phải lỗi được sửa trong JDK không? Tôi có nên mở lại hoặc tải xuống JDK mới không? – ripper234

+0

hs16 (b04) là phiên bản điểm nóng, không phải là phiên bản JRE. Dường như bản sửa lỗi nằm trong phiên bản 1.6.0_16-b02 sau phiên bản của bạn, vì vậy bạn nên tải xuống phiên bản mới nhất (1.6.0_17). – Mocky

0

ripper234, tôi chỉ cần chạy này trên máy tính của tôi và nó luôn luôn dừng lại không có vấn đề những gì tôi sử dụng giá trị cho các bản in và mà ngắt để sử dụng. Tôi đang sử dụng jdk1.6.0_16. nhìn vào javadoc, có lẽ nó có cái gì đó để làm với thực tế là bị gián đoạn() xóa trạng thái (bị gián đoạn) sau mỗi cuộc gọi và isInterrupted() thì không. thực tế là nó hoạt động đôi khi cho jerome, luôn luôn cho tôi, và không bao giờ (?) cho bạn có thể chỉ ra một sự khác biệt trong jdks chúng tôi đang sử dụng hoặc tốc độ của máy của chúng tôi. nếu nó có liên quan đến việc thanh toán bù trừ của nhà nước, điều đó có thể giải thích sự thay đổi.