1.线程阻塞主要有以下四方面原因:
a.线程执行了Thread.sleep(int n)方法,线程放弃CPU,睡眠n毫秒,然后恢复运行.
b.线程要执行一段同步代码,由于无法获得相关的同步锁,只好进入阻塞状态,等到获得了同步锁,才能恢复运行.
c.线程执行了一个对象的wait()方法,进入阻塞状态,只有等到其他线程执行了该对象的notify()或notifyAll()方法,才可能将其唤醒.
d.线程执行IO操作或进行远程通信时,会因为等待相关的资源而进入阻塞状态.
具体到进行远程通信时,在客户端,线程在以下可能进入阻塞状态:
a.请求与服务器建立连接时,即当线程执行Socket的带参数的构造方法,或执行Socket的connect()方法时,会进入阻塞状态,直到连接成功.此线程才从Socket的构造方法或connect()方法返回.
b.线程从socket的输入流读入数据时,如果没有足够数据,就会进入阻塞状态,直到读到了足够的数据,或者达到输入流的末尾,或者出现了异常,才从输入流的read()方法返回或异常中断.输入流中有多少数据才算足够呢?看read方法类型.
int read():只要输入流有一个字节就足够;
int read(byte[] buff)只要输入流中的字节数与参数buff的数组长度相同就足够.
String readLine():只要输入流中有一行字符串就算足够.注:InputStream没有readLine方法,在过滤流BufferedReader中有此方法.
c.线程向socket输出流写一批数据时,可能会进入阻塞状态,等到输出了所有的数据.或者出现异常,才从输出流的write方法返回或异常中断.
d.调用socket的setSoLinger方法设置了关闭Socket的延迟时间,那么当线程执行Socket的close方法时,会进入阻塞状态,直到底层socket发送完的所有剩余数据,或者超过了setSoLinger()方法设置的延迟时间,才从close方法返回.
在服务器程序中,线程在以下情况下可能会进入阻塞状态.
a.线程执行ServerSocket的accept方法,等待客户的连接,直接接收到了客户连接.才从Accept()方法返回.
b.线程从Socket的输入流读入数据时,如果输入流没有足够的数据,就会进入阻塞状态.
c.线程向Socket的输出流写一批数据时,可能会进入阻塞状态,等到出了所有的数据,或者出现异常中断.
ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非阻塞通信.
SocketChannel:Socket的替代类,支持阻塞通信与非阻塞.
Selector:为ServerSocketChannel监控接收连接就绪事件,为SocketChannel监听连接就绪,读就绪和写就绪事件.
SelectionKey:代表ServerSocketChannel及SocketChannel向Selector注册事件的句柄.当一个SelectionKey对象位于Selector对象的Selected-keys集合时,就表示与这个SelectionKey对象相关的事件发生了.
Selector类:
all-keys:当前所有向Selector注册的SelectionKey的集合,
selected-keys:相关事件已经被Selector捕获的Selection的集合.
cancelled-keys:已被取消的SelectionKey的集合.
android spp socket 阻塞 socket connect阻塞
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
linux之socket编程
linux之socket编程
数据 端口号 IP