2010-12-13 29 views
61

Trong ngữ cảnh của Java, tôi tạo một luồng mới để đọc đầu vào mạng khi mở một cửa sổ GUI, và khi tôi đóng cửa sổ, tôi muốn giải phóng tài nguyên ổ cắm và chấm dứt chuỗi ngay lập tức. Bây giờ tôi đang sử dụng phương pháp setSoTimeout, nhưng tôi không muốn chờ đợi các ngoại lệ timeout. Ai có thể đưa ra một số gợi ý? Cảm ơn!Làm thế nào để chấm dứt một thread chặn trên hoạt động IO socket ngay lập tức?

+11

Tôi không hiểu tại sao điều này có một -1?!? Tôi nghĩ câu hỏi khá rõ ràng và ngay tại chỗ. –

Trả lời

53

Có (khả năng) ba cách để làm điều này:

  • Calling Socket.close() trên socket sẽ đóng liên InputStreamOutputStream đối tượng, và gây ra bất kỳ đề chặn Socket hoặc (liên quan) dòng hoạt động để được bỏ chặn. Theo javadoc, các hoạt động trên chính socket sẽ ném một SocketException.

  • Gọi Thread.interrupt() sẽ (trong một số trường hợp không được chỉ định) sẽ làm gián đoạn hoạt động I/O chặn, khiến nó ném một số InterruptedIOException.

    Lưu ý báo trước. Rõ ràng cách tiếp cận "ngắt()" không hoạt động trên các nền tảng Java "hiện đại nhất". (Nếu ai đó có thời gian và độ nghiêng, họ có thể điều tra các trường hợp mà phương pháp này hoạt động. Tuy nhiên, thực tế là hành vi là nền tảng cụ thể nên đủ để nói rằng bạn chỉ nên sử dụng nó nếu bạn chỉ cần ứng dụng của bạn để làm việc trên một nền tảng cụ thể. Tại thời điểm đó, bạn có thể dễ dàng "thử" cho chính mình.)

  • Cách thứ ba có thể thực hiện là gọi Socket.shutdownInput() và/hoặc Socket.shutdownOutput(). Các javadocs không nói rõ ràng những gì xảy ra với các hoạt động đọc và/hoặc ghi hiện đang bị chặn, nhưng nó không phải là không hợp lý khi nghĩ rằng chúng sẽ bỏ chặn và ném một ngoại lệ. Tuy nhiên, nếu javadoc không nói điều gì xảy ra thì hành vi đó sẽ được giả định là nền tảng cụ thể.

+1

Xin vui lòng, trong những trường hợp nào sẽ thread.interrupt() làm gián đoạn một hoạt động I/O chặn? –

+2

Xu DXn - nó không phải là tài liệu. Một số luồng thực hiện điều này, những luồng khác thì không. Để biết chi tiết đẫm máu, hãy đọc mã nguồn OpenJDK. Điểm tôi đang cố gắng tạo ra là nó có thể có hoặc không hoạt động. –

+1

khá chắc chắn hầu hết các triển khai jvm làm _not_ hỗ trợ các hoạt động io gián đoạn. tôi nghĩ rằng có lẽ mặt trời solaris jvm hỗ trợ nó tại một thời điểm. – jtahlborn

12

Tôi biết câu hỏi này là cũ nhưng không ai dường như đã giải quyết được "bí ẩn" của Thread.interrupt() trên "nền tảng hiện đại" tôi đã thực hiện một số nghiên cứu.

Điều này được kiểm tra trên Java 8 trên Windows7 (64-bit) (nhưng nó cũng có thể đúng đối với các nền tảng khác).

Calling Thread.interrupt() không không ném một InterruptedIOException gì xảy ra là phương pháp InputStream.read() trả về với -1Thread.interrupted() -flag được thiết lập.

Vì vậy, những điều sau đây có thể được coi là một 'điều chỉnh' read() ném InterruptedIOException:

static final int read(Socket socket, byte[] inData) 
    throws SocketTimeoutException, // if setSoTimeout() was set and read timed out 
      InterruptedIOException, // if thread interrupted 
      IOException    // other erors 
{ 
    InputStream in = socket.getInputStream(); 

    int readBytes = in.read(inData, 0, inData.length); 

    if (Thread.interrupted()) 
    { 
     throw new InterruptedIOException("Thread interrupted during socket read"); 
    } 

    return readBytes; 
} 
+1

Câu trả lời này xứng đáng được nhiều phiếu bầu hơn vì hành vi của Java khi bị gián đoạn trong các hoạt động của luồng đầu vào/đầu ra không phải là điều mà nhiều người mong đợi. –

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