线程切换
线程创建之后,调用start()方法开始运行。当线程执行wait()方法之后,线程进入等待状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态,而超时等待状态相当于在等待状态的基础上增加了超时限制,也就是超时时间到达时将会返回到运行状态。当线程调用同步方法时,在没有获取到锁的情况下,线程将会进入到阻塞状态。线程在执行Runnable的run()方法之后将会进入到终止状态。
等待状态和阻塞状态的区别、
等待状态和阻塞状态都表示线程暂时停止执行,但是它们的原因和发生场景不同。
等待状态是指一个线程调用了Object类的wait()方法,使得线程进入等待状态,直到被notfy()或notfyAll()方法唤醒。等待状态通常是为了实现线程间的协作,等待某个条件的出现后再继续执行。
阻塞状态是指一个线程因为某些原因(如等待ⅣO操作完成或试图获得一个锁)而暂停执行,直到满足特定条件后再继续执行。阻塞状态通常是由于外部原因导致的,例如等待用户输入、等待网络传输等。
总的来说,等待状态是由于线程自身的行为导致的,而阻塞状态是由于外部条件的限制导致的。
处于等待状态的线程和处于阻塞状态的线程有区别吗
注意这里说的是资源
等待状态的线程通常是在等待某个条件满足后才能继续执行,例如等待一个资源被释放后才能使用。
而阻塞状态的线程则是被一个外部条件所阻塞,例如等待用户输入或等待网络连接等情况。
在等待状态下,线程会主动释放所占用的资源,而在阻塞状态下,线程会一直占用资源直到外部条件满足才会被唤醒
线程阻塞状态和挂起状态的区别
线程阻塞状态和挂起状态的区别在于,线程阻塞状态是指线程因为等待某个条件而被暂停执行,而挂起状态是指线程被主动暂停执行,等待被恢复执行。在阻塞状态下,线程会一直等待条件满足后才能继续执行,而在挂起状态下,线程需要等待外部的恢复操作才能继续执行。
注意
Java将操作系统中的运行和就绪两个状态合并称为运行状态。阻塞状态是线程
阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态,但是阻塞在
java.concurrent包中Lock接口的线程状态却是等待状态,因为java.concurrent包中Lock接口对于
阻塞的实现均使用了LockSupport类中的相关方法。
中断v
中断可以理解为线程的一个标识位属性,它表示一个运行中的线程是否被其他线程进行
了中断操作。中断好比其他线程对该线程打了个招呼,其他线程通过调用该线程的interrupt()
方法对其进行中断操作。
线程通过检查自身是否被中断来进行响应,线程通过方法isInterrupted()来进行判断是否
被中断,也可以调用静态方法Thread.interrupted()对当前线程的中断标识位进行复位。如果该
线程已经处于终结状态,即使该线程被中断过,在调用该线程对象的isInterrupted()时依旧会返
回false。
从Java的API中可以看到,许多声明抛出InterruptedException的方法(例如Thread.sleep(long
millis)方法)这些方法在抛出InterruptedException之前,Java虚拟机会先将该线程的中断标识位清除,然后抛出InterruptedException,此时调用isInterrupted()方法将会返回false。
安全的去停止线程
中断状态是线程的一个标识位,而中断操作是一种简便的线程间交互方式,而这种交互方式最适合用来取消或停止任务。除了中断以外,还可以利用一个boolean变量来控制是否需要停止任务并终止该线程.
示例在执行过程中,main线程通过中断操作和cancel()方法均可使CountThread得以终止。
这种通过标识位或者中断操作的方式能够使线程在终止时有机会去清理资源,而不是武断地
将线程停止,因此这种终止线程的做法显得更加安全和优雅。
stop为什么不安全
stop方法:强制停止一个正在运行的线程,无论此时线程是何种状态。
stop方法在停止线程时需要自行指定线程退出逻辑,否则线程会立即退出,不做任何清理操作,非常不安全,会造成数据不一致问题。