线程阻塞时的特点:
该线程放弃CPU的使用权,暂停运行,只有当阻塞的原因消除后才回到就绪状态进行运行
被其他的线程中断,该线程也会推出阻塞状态,同时抛出InterruptedException的异常
导致阻塞的原因主要为三种:
一般线程中的阻塞:
线程执行了 Thread.sleep (int n) 方法,该线程放弃CPU的使用,沉睡 n 毫秒,然后恢复运行
线程执行了一段同步代码,由于无法获得相关的同步锁,只能进入阻塞状态,等获取了同步锁,才能恢复运行
线程执行了一个对象的 wait ( )方法,进入阻塞状态,只有等到其他线程执行了该对象的 notify ( ) 或 notifyAll ( )方法,才能将其唤醒
线程执行 I/O 操作 或 进行远程通信 时,会因为等待相关的资源而进入阻塞状态 (例如,当线程执行System.in.read()方法时,如果用户没有向控制台输入数据,该线程会一直等读到用户的输入数据才会从read () 方法返回)
Socket客户端的阻塞:
向服务器请求连接时,当线程执行Socket的带参数构造方法 或者 调用connect () 方法,进入阻塞状态,直到连接成功,此线程才会从Socket的构造方法或connect () 方法返回
线程从Socket的输入流读取数据时,如果没有足够的数据,就会进入阻塞状态,直到读取了足够的数据,或者到达输入流的末尾,或者出现异常,才会从输入流的read () 方法返回或异常中断 (例如,通过BufferedReader类使用readLine () 方法时,线程再没有读出一行数据之前,数据都是不足的,会处于阻塞状态)
调用Socket的setSoLinger () 方法关闭了Socket延迟,当执行Socket的close () 方法时,会进入阻塞状态,直到底层Socket发送完所有的剩余数据
Socket服务器的阻塞:
线程执行ServerSocket的accept () 方法,等待客户端的连接,直到收到客户的连接,才从accept () 方法中返回一个Socket对象
从Socket输入流读取数据时,如果输入流没有足够的数据,就会进入阻塞状态
线程向Socket的输出流写入一批数据,可能进入阻塞状态,当线程阻塞时,会降低程序的效率
温馨提示:
Java.nio 提供了支持 非阻塞通信 的类
非阻塞方法:
当线程执行执行这些方法时,如果操作还没有就绪时,就立即返回,不会阻塞着去等待操作就绪