线程的阻塞与休眠

进程、线程状态
进程一般分五个状态:创建,就绪,运行,阻塞,结束
线程一般分四个状态:就绪,运行,阻塞,死亡

针对进程或线程各个状态的区别,从名字大概就可以看出来了。针对阻塞、休眠,挂起,又怎么考虑区别呢?实际使用时,经常称呼阻塞后进入挂起,因为可以认为挂起就是一个动作,进入阻塞态或休眠态。休眠和挂起并没有写入线程、进程生命周期的状态。

1、主动,被动角度
阻塞pend是被动,在访问临界资源(锁等)时,被阻塞了
休眠和挂起,一般是主动(或由父进程发起挂起)因此恢复也应该要主动完成,休眠在休眠时,就知道了计划休眠时长sleep(10),挂起suspend需要等待resume。
时间片到了,也会挂起线程。

2、CPU,内存角度
阻塞会释放CPU,一般不释放内存。
挂起一般会继续占用CPU,一般会释放内存,被转移到外存。
休眠一般会释放CPU,低优先级或其它优先级可以得到执行。也有说sleep()指线程被调用时,占着CPU不工作,形象的说明为“占着CPU”睡觉

3、线程锁等角度
阻塞不会释放锁
挂起会释放锁
休眠也不会释放锁

4、调度角度
任务调度是操作系统来实现的,任务调度时,直接忽略挂起状态的任务,
但是会顾及处于pend下的任务,当pend下的任务等待的资源就绪后,就可以转为ready了。ready只需要等待CPU时间

5、分享网上的两个段子
5.1异步同步阻塞非阻塞
老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)
老张觉得自己有点傻
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~ 的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)
老张觉得这样傻等意义不大
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
老张觉得自己聪明了。

5.2 阻塞,挂起,睡眠(休眠)
对线程的控制就好比你控制了一个雇工为你干活。你对雇工的控制是通过编程来实现的。
挂起线程的意思就是你对主动对雇工说:“你睡觉去吧,用着你的时候我主动去叫你,然后接着干活”。
使线程睡眠的意思就是你主动对雇工说:“你睡觉去吧,某时某刻过来报到,然后接着干活”。
线程阻塞的意思就是,你突然发现,你的雇工不知道在什么时候没经过你允许,自己睡觉呢,
但是你不能怪雇工,肯定你 这个雇主没注意,本来你让雇工扫地,结果扫帚被偷了或被邻居家借去了,
你又没让雇工继续干别的活,他就只好睡觉了。至于扫帚回来后,雇工会不会知道,会不会继续干活,你不用担心,
雇工一旦发现扫帚回来了,他就会自己去干活的。因为雇工受过良好的培训。这个培训机构就是操作系统。
sleep()和wait()函数的区别:
(1)两者比较的共同之处是:两个方法都是使程序等待多少毫秒。
(2)最主要区别是:sleep()方法没有释放锁。而wait()方法释放了锁,使得其他线程可以使用同步控制块或者方法。
(3)它们的语法使用不同。Sleep()是线程类(Thread)的方法,当一个线程调用Sleep()方法后,此线程会暂停执行一段时间,将执行机会交给其他线程,但是监控状态依然保持,到设定的时间后会自动恢复,而且可以在任何地方使用。另一方面,wait()是Object类的方法,当一个线程对某个对象调用wait()方法时,会导致本线程放弃该对象的锁,进入等待该对象的等待锁定池中。只有当针对这个对象发出notify()方法或notifyAll()后,本线程才进入对象锁定池准备获得对象锁进入运行状态。

(4)他们的唤醒方式也有所不同。Sleep()方法的唤醒是由时间驱动的,而wait()的唤醒则是通过调用notify()或notifyAll()方法来实现的。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值