当连接到一个套接字时,当前线程将会被阻塞直到建立连接或产生超时为止。通过套接字读写数据时也是一样。
在交互式的应用中,也许会考虑为用户提供一个功能,用已取消那些看似不会成功的连接,但是,当线程因套接字长时间无法响应而发生阻塞时,无法通过调用interrupt来解除阻塞。
如此,可用java.nio包提供的一个新特性——SocketChannel类中断套接字操作
1 | SocketChannel channel=SocketChannel.open(new InetSocketAddress(host,port)); |
channel并没有与之相关联的流,实际上,它所拥有的read和write方法都是通过调用Buffer对象来实现的。ReadableByteChannel接口和WritableByteChannel都声明了这两个方法。如果不想处理缓存,可以使用Scanner类来读取信息,因为Scanner有一个带ReadableByteChannel参数的构造器:
1 | Scanner in = new Scanner(channel); |
如果线程发生中断,那么这些操作将不会陷入阻塞,而是以抛出异常的方式结束
示例程序如下
其对比了可中断套接字与阻塞套接字:服务器将连续发送数字,每发送一个数字停一下。点击两个按钮中的任何一个都会启动一个线程来连接服务器并打印输出。第一个使用可中断套接字,第二个使用阻塞套接字,启动之后,再点击取消时,可中断套接字一直工作良好,阻塞套接字却只能有效工作有限次,原因不明。
1 | import java.awt.*; |
未解决问题:阻塞套接字未能正常工作,可能与其底层实现机制有关