2013-03-20 47 views
10
  1. Tại sao một chủ đề ngủ cần thử bắt để Ngắt ngoại lệ bị gián đoạn?
  2. Tại sao một giấc ngủ thậm chí phát ra một lỗi Ngoại lệ bị gián đoạn? Đây là hai câu hỏi tôi thực sự muốn tìm hiểu về lập trình java Tôi đã tìm kiếm thông qua google và tôi vẫn chưa tìm thấy giải thích rõ ràng là tại sao hai điều này lại xảy ra.

Trả lời

1

1.- Bởi vì một Chủ đề không thể hoàn thành việc thực hiện bình thường của nó nếu bạn ngắt nó, và bạn cần phải nắm bắt điều đó để chuẩn bị làm điều gì đó. 2.- Bởi vì một thread chờ đợi là khác nhau từ một thread bị gián đoạn, một thread chờ đợi có thể được nối lại, nhưng một thread bị gián đoạn đã được thực hiện kết thúc.

+0

Vì vậy, bằng cách tuyên bố một ngoại lệ bị gián đoạn, tôi có thể tự do bấm vào bất kỳ nút nào tôi đã nhập vào trong khi những thứ tôi đưa vào giấc ngủ đang ngủ? Vì đó là những gì tôi đã hiểu cho đến nay –

+0

kiểm tra điều này http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#interrupt%28%29 – jsedano

3

An InterruptedException được ném khi chuỗi bị chặn/chờ và bị gián đoạn bởi một luồng khác (bằng phương tiện Thread.interrupt). Hãy suy nghĩ về nó như một yêu cầu chấm dứt ngay lập tức, mà không bị những hạn chế của Thread.stop().

Bằng cách này, ngay cả khi bạn hướng dẫn một chủ đề ngủ trong vài năm, bạn vẫn có thể làm gián đoạn chuỗi đó.

The recommended practice đang hủy bất kỳ thứ gì bạn đang xử lý khi số InterruptedException bị ném.

+0

Ồ, ví dụ tôi có hai khung, frame1 và frame2. Frame1 có một nút cho thấy khung 2. Bằng cách tuyên bố một ngoại lệ bị gián đoạn, tôi có thể nhấp vào nút đó để hiển thị frame2 của tôi trong khi frame1 đang ngủ? –

+0

Xin lỗi, tôi không có đủ kinh nghiệm với đồng thời trong AWT/Swing. Tôi sử dụng các chủ đề cho các tác vụ nền. Nếu bạn có thể thuật lại câu hỏi của mình không sử dụng GUI, tôi sẽ rất vui được trả lời. – Javier

+0

Điều thú vị là tôi đã quan tâm đến java cho gui của nó và tôi chỉ học một tuần và tôi nghĩ đó là một ý tưởng tồi để bắt đầu kể từ khi tôi phải biết những điều cơ bản đầu tiên (Mọi thứ không liên quan đến gui). Mặc dù tôi hy vọng đây là một ví dụ tốt, tôi sẽ ngủ một tuyên bố rằng thêm hai con số và một trong những điều tôi đã nhận thấy về ngủ là nó "đóng băng" yung chương trình hoặc không chỉ xảy ra trong gui? (xin lỗi tôi thực sự không biết). Và bằng cách thêm một ngoại lệ bị gián đoạn, bạn có thể tự do làm bất kỳ nội dung nào khác mà bạn muốn thực hiện trong khi câu lệnh mà bạn yêu cầu để ngủ đang ngủ? –

0

Có một ví dụ sạch như thế nào ngoại lệ Interrupted có thể được vứt ở đây: http://www.javamex.com/tutorials/threads/thread_interruption.shtml

Và một thảo luận về sleep()yield() đây: http://www.coderanch.com/t/508657/threads/java/Sleep-Yield-state

+0

Các chủ đề có thể được truy cập từ bên ngoài một cách đồng thời trong khi nó đang làm việc hoặc ngủ (đó là tất cả những niềm vui!): Sau đó nó có thể được yêu cầu để thoát khỏi "xấu", đó là lý do tại sao ngoại lệ được nâng lên. – Benj

+0

Ôi nó giống như bạn bị nhốt trong một căn phòng với một anh chàng đang ngủ, bằng cách thêm một ngoại lệ gián đoạn, bạn có thể mở khóa phòng và làm những thứ khác "hoặc" có một xô nước trong tay và "đánh thức" anh chàng bằng cách dừng lại nó ngủ? Xin lỗi tôi đã tạo ra các tình huống thực tế để áp dụng cho những vấn đề này để giúp tôi hiểu chúng tốt hơn. –

+0

Chuyện gì, nhưng * xấp xỉ * là vậy;) – Benj

0

Đó là vì sleep() khả năng có thể chặn vĩnh viễn/một thời gian dài như vậy bạn cần một cách để có thể hủy bỏ hành vi này. Bởi vì nó không hoàn thành "bình thường" khi bạn làm gián đoạn hành động, bạn có thể cần phải thực hiện một số hành động bồi thường hoặc khắc phục cụ thể, ví dụ: để gửi cảnh báo rằng bạn chưa bao giờ nhận được thông báo, dọn sạch tài nguyên, v.v.
Có một tốt developer works article on the subject.

+0

Vì vậy, bằng cách thêm một ngoại lệ bị gián đoạn, tôi có thể tự do đóng chương trình của tôi trong khi ngủ hoặc làm cái gì khác trong khi nó ngủ? –

+0

Giống như nếu bạn muốn đóng ứng dụng của mình thì luồng ngủ của bạn bị gián đoạn và có cơ hội để xóa bỏ hoạt động kinh doanh của mình trước khi tắt, ví dụ: ghi trạng thái vào một db, đăng nhập một thông báo. – James

1

Khi bạn yêu cầu một chủ đề để ngủ, hành vi dự kiến ​​cho chủ đề đó là ngủ trong nhiều thời gian. Vì vậy, nếu giấc ngủ bị gián đoạn, nó sẽ ném InterruptedException để chỉ ra rằng nó không thể hoàn thành nhiệm vụ. Và bạn có thể muốn chăm sóc những gì nên được thực hiện nếu nó bị gián đoạn.

+0

Nếu tôi đặt một ngoại lệ bị gián đoạn thông qua bắt cố gắng, ngủ thread sẽ không "đóng băng" chương trình của tôi trong khi làm điều ngủ của nó? và tôi có thể thực hiện các tác vụ khác như nhấp vào các nút từ chương trình của mình trong khi câu lệnh tôi đưa vào chế độ ngủ đang ngủ? –

+0

Mỗi khi bạn bấm vào một nút, một chuỗi mới sẽ được tạo và nó sẽ gọi phương thức actionPerformed với một đối số ActionEvent. –

+0

Trường hợp chính xác bạn đã đặt phương thức sleep()? –

0

Giấc ngủ và ngắt không liên quan đến ngữ nghĩa. Nó chỉ là các nhà thiết kế Java nghĩ rằng khi bạn muốn thread của bạn ngủ, đó là một cơ hội tốt để nhắc nhở bạn về các ngắt. Điều này giống như Duke nói "Có vẻ như bạn đang cố gắng ngủ, bạn cũng muốn làm cho luồng của mình trở thành công dân tốt bằng cách đảm bảo rằng nó phản hồi các sự kiện ngắt đúng cách, khi cần một cách để kết thúc sự kiện đột ngột ở giai đoạn sau trong dự án của bạn phát sinh? "

Vì vậy, ai sẽ thường xuyên xem mã như thế này:

try { 
    Thread.sleep(1000); 
} catch (InterruptedException ie) { 
    //Don't worry about it. 
} 

Đôi khi người ta nói điều này được coi là xấu thực hành. Nhưng nếu bạn không có kế hoạch sử dụng cơ sở ngắt trong chương trình của bạn, thì những trường hợp ngoại lệ này sẽ không bao giờ bị ném, vì vậy bạn phải tự hỏi liệu mình có thực hiện thêm công việc để chăm sóc các ngoại lệ này hay không, trong trường hợp bạn quyết định thêm tính năng gián đoạn cho chương trình của bạn một thời gian sau đó, có ý nghĩa.Đây là một trong những điều mà các nhà thiết kế Java nhấn mạnh rằng mỗi thread nên làm - rằng bạn có thể interrupt() nó, và nó sẽ nhanh chóng và sạch sẽ hủy bỏ những gì nó đang làm. Tôi nghĩ điều đó không cần thiết trong nhiều trường hợp, nhưng mọi người sẽ xem xét mã của bạn, xem điều này và vẫn nói "eew, thực hành xấu!"

The official Java tutorial explains interrupts. Về cơ bản, nếu bạn có một thread t thực hiện một số xử lý, và sau đó người dùng muốn hủy nó, từ một chủ đề khác, bạn sẽ gọi t.interrupt(). Trong mã đang chạy trên chuỗi t, bất cứ khi nào nó sleep() s hoặc wait() s, v.v., một số InterruptedException sẽ bị ném. Nếu nó không làm bất cứ điều gì trong số này, sau đó nó có thể (nên) cũng tìm ra nếu nó đã bị gián đoạn sử dụng Thread.interrupted() theo thời gian. Trong tất cả các cách tìm hiểu về các ngắt, nó nên từ bỏ những gì nó đang làm và làm sạch ASAP. (Có nghĩa là: nếu nó làm như vậy, thì hành vi này có thể hữu ích cho bạn hoặc ai đó - đó là ý tưởng gián đoạn.)

Vì vậy, Java làm cho ngoại lệ này được kiểm tra theo phương pháp sleep(..), buộc bạn phải suy nghĩ về việc sử dụng cơ sở này. Phần khác của lý do là nếusleep(..) bị gián đoạn, sau đó nó sẽ thức dậy sớm, và đó là một sự kiện đặc biệt. (Nhưng hãy nhớ rằng, có "nếu".)

Điều quan trọng là ngắt không chỉ xảy ra mà không có lý do gì. Chúng xảy ra nếu bạn viết mã để làm cho chúng xảy ra, hoặc nếu người khác làm, những người khởi chạy chủ đề của bạn và có nhu cầu hủy bỏ các hoạt động của họ. Vì vậy, đây là nguyên nhân gây ra Thread.sleep(..) để ném một số InterruptedException. Bạn làm. Và nếu bạn không, thì bạn vẫn cần phải nắm bắt nó.


Chỉnh sửa. Bằng cách này, nó sẽ là một thực hành tốt hơn để làm điều đó theo cách này:

try { 
    Thread.sleep(1000); 
} catch (InterruptedException ie) { 
    throw new UnsupportedOperationException("Interrupts not supported.", ie); 
} 

Vì vậy, nếu bạn hoặc người khác, không bao giờ cố gắng để gây cản trở chủ đề này do nhầm lẫn sau, sau đó khi họ đi đến kiểm tra nó , họ sẽ được nhắc rằng tính năng này không được triển khai. (UnsupportedOperationException là một phân lớp của RuntimeException, vì vậy nó không được chọn.)