starvation(“全栈2019”Java多线程第二十二章:饥饿线程(Starvation)详解)

难度

初级

学习时间

30分钟

适合人群

零基础

开发语言

Java

开发环境
  • JDK v11
  • IntelliJ IDEA v2018.3
友情提示
  • 本教学属于系列教学,内容具有连贯性,本章使用到的内容之前教学中都有详细讲解。
  • 本章内容针对零基础或基础较差的同学比较友好,可能对于有基础的同学来说很简单,希望大家可以根据自己的实际情况选择继续看完或等待看下一篇文章。谢谢大家的谅解!
1.温故知新

前面在《“全栈2019”Java多线程第十六章:同步synchronized关键字详解》一章中介绍了synchronized关键字

《“全栈2019”Java多线程第十七章:同步锁详解》一章中介绍了同步代码块/方法中的同步锁

《“全栈2019”Java多线程第十八章:同步代码块双重判断详解》一章中介绍了同步代码块中的双重判断

《“全栈2019”Java多线程第十九章:死锁详解》一章中介绍了死锁

《“全栈2019”Java多线程第二十章:同步方法产生死锁的例子》一章中介绍了同步方法产生死锁的例子

Strava

《“全栈2019”Java多线程第二十一章:同步代码块产生死锁的例子》一章中介绍了同步代码块产生死锁的例子

现在我们来讲解饥饿线程(Starvation)

2.什么是饥饿线程?

看到“饥饿”一词,大家是不是想到我们人,因为人也会饿。那么,我们就来通过人饥饿来举例说明饥饿线程。

首先,我们人也会饿:


人饿了之后就会自己去做东西吃或者点外卖,无论怎样都是获取食物:


得到食物之后,吃饱了就不饿了:


以上是人-饥饿-获取食物-吃饱了的例子。

如果只有人-饥饿,没有后面的获取食物-吃饱了,那人是不是处于饥饿状态?

是的。

如果此时把人看作是线程的话,那么饥饿线程你体会到了吗?

饥饿线程就是线程-饥饿。此处的饥饿描述了一种情况,即线程无法获得对共享资源的定期访问,并且无法取得进展。

举一个例子,我们有一个线程A:


此时它要去执行一个同步方法:


但是这个同步方法需要执行很久:


此时这个线程A就很会占据这个共享资源很长时间,导致其它线程无法进行访问。

为什么其它线程无法访问呢?

因为同步锁在任何时刻最多只能被一个线程拥有,所以其它线程没有同步锁进不去,从而无法访问。

以上只是饥饿线程情况的其中一种,接下来,我们就来一个饥饿线程的例子。

3.饥饿线程例子

就把上一小节最后的例子用程序描述出来。

首先,我们得有一个线程:


然后,我们得来一个资源类,就叫Starvation类(Starvation是饥饿的意思):


接着,我们要在Starvation类中定义一个同步方法(方法有无返回值都可以,只需该方法执行时间很长即可):


大家清楚同步方法里面怎么写吗?

根据饥饿线程的定义,我们线程在执行同步方法的时候,这个同步方法需要很久才能执行完,所以为了表示需要很久才能执行完此同步方法,可以在该同步方法内部睡5秒,当然了,睡眠时间大家自己写的时候可以自定:


好了,资源类已写好,接着就是让线程去访问该资源。

创建好我们的资源对象:


接着,通过匿名内部类的方式实现Runnable接口:


然后,在run()方法中访问资源对象的同步方法:


我们还可以再创建出一个线程,也去访问该资源对象的同步方法:


目的就是想说明饥饿线程情况中当一个线程长期占据共享资源时,还阻止了其它线程的访问。

最后,我们可以启动线程了:


至此,饥饿线程例子书写完毕,整理以上代码后再运行程序。

演示:

请写一个饥饿线程的例子。

请观察程序代码及结果。

代码:

Starvation类:


Main类:


结果:


从运行结果来看,程序没什么问题。

有小伙伴看到这里可能会说这线程执行时间不长啊,也不会导致其它线程等待很久时间。

其实不然,这里我们用线程睡眠来代替了执行时间,而且睡眠时间也不长,为5秒钟,试想一下,如果睡眠时间为1小时呢?只有执行时间过长才会发生饥饿线程这种情况。

GitHub

本章程序GitHub地址:https://github.com/gorhaf/Java2019/tree/master/Thread/Starvation

总结
  • 饥饿描述了一种情况,即线程无法获得对共享资源的定期访问,并且无法取得进展。
  • 例如,假设一个对象提供了一个通常需要很长时间才能返回的同步方法。如果一个线程经常调用此方法,则其他线程无法进入执行。

至此,Java中饥饿线程(Starvation)相关内容讲解先告一段落,更多内容请持续关注。

答疑

如果大家有问题或想了解更多前沿技术,请在下方留言或评论,我会为大家解答。

上一章

“全栈2019”Java多线程第二十一章:同步代码块产生死锁的例子

下一章

“全栈2019”Java多线程第二十三章:活锁(Livelock)详解

学习小组

加入同步学习小组,共同交流与进步。

  • 方式一:关注头条号Gorhaf,私信“Java学习小组”。
  • 方式二:关注公众号Gorhaf,回复“Java学习小组”。
全栈工程师学习计划

关注我们,加入“全栈工程师学习计划”。


版权声明

原创不易,未经允许不得转载!

您可以还会对下面的文章感兴趣

使用微信扫描二维码后

点击右上角发送给好友