线程的中断和阻塞的区别

qq_32466561 2018-12-15 04:38:39
线程的中断和阻塞的区别,中断后还能否还原,中断和阻断是不是一个意思
...全文
1074 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
_jant 2018-12-17
  • 打赏
  • 举报
回复
线程阻塞

一个线程进入阻塞状态的原因可能如下(已排除Deprecated方法):

sleep()

sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;

当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象锁并没有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。

wait()

调用wait()/1.5中的condition.await()使线程挂起,直到线程获取notify()/notifyAll()消息,(或者在Java SE5中java.util.concurrent类库中等价的signal()/signalAll()消息),线程才会进入就绪状态;

wait()调用会释放当前对象锁(monitor),这样其他线程可以继续进入对象的同步方法。参见上一篇文章线程间协作——wait & notify & notifyAll

另外,调用join()也会导致线程阻塞,因为源码中join()就是通过wait()实现的;

等待I/O;

class Demo3 implements Runnable throws InterruptedException{
private InputStream in;
public void run(){
in.read();
}
}
1
2
3
4
5
6
无法持有锁进入同步代码

进入同步代码前无法获取锁,比如试图调用synchronized方法,或者显示锁对象的上锁行为ReentrantLock.lock(),而对应锁已被其他线程获取的情况下都将导致线程进入阻塞状态;

注意:yield()并不会导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

线程中断

线程中断可以在线程内部设置一个中断标识,同时让处于(可中断)阻塞的线程抛出InterruptedException中断异常,使线程跳出阻塞状态。相比其他语言,Java线程中断比较特殊,经常会引起开发人员的误解。因为中断听起来高深复杂,实质原理上非常简单。

中断原理

Java中断机制是一种协作机制,也就是说通过中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。这好比是家里的父母叮嘱在外的子女要注意身体,但子女是否注意身体,怎么注意身体则完全取决于自己。

Java中断模型也是这么简单,每个线程对象里都有一个boolean类型的标识(不一定就要是Thread类的字段,实际上也的确不是,这几个方法最终都是通过native方法来完成的),代表着是否有中断请求(该请求可以来自所有线程,包括被中断的线程本身)。例如,当线程t1想中断线程t2,只需要在线程t1中将线程t2对象的中断标识置为true,然后线程2可以选择在合适的时候处理该中断请求,甚至可以不理会该请求,就像这个线程没有被中断一样。
十八道胡同 2018-12-17
  • 打赏
  • 举报
回复
https://blog.csdn.net/higherzjm/article/details/82700264

50,543

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧