【Java】基础34:线程之间的合作?

coding


今天是我自学Java的第34天。

感谢你的观看,谢谢你。

话不多说,开始今天的学习:。

首先回顾下线程同步:

线程同步其实讲的就是线程之间的竞争。

通俗一点说就是:对于同一个任务,因为Java虚拟机的抢占式调度,线程一、线程二都抢着做,线程一还没做完,线程二就跑进来横插一脚,说白了不就好比两个人在互相竞争么?

对于这种情况,我们采用了同步机制来解决,让它们一次只能执行一个线程:线程一执行完,线程二才能进去。

那么现在问题来了:

线程之间既然有竞争,那有没有合作呢?

答案是有的,有竞争自然也会有合作。

用一个案例来说明:

刘小爱是个吃货,要去包子铺吃包子。

现有一个设定:刘小爱1次只能吃1个包子,包子铺1次只能生产1个包子,一有包子刘小爱就吃,吃完后,包子铺就开始生产,包子一生产出来,刘小爱就继续吃……

先不管符不符合现实逻辑哈,反正设定是这样的。

面对这个问题,该怎么办?

刘小爱是一个线程,包子铺也是一个线程,它们会操作同一个对象,也就是包子。

一、包子类

创建一个包子类,代码如下:

①包子类里面有一个属性叫isHave。

isHave用于判断是否有包子:如果为true,表示有包子;如果为false,表示没有包子。

②get/set方法用于获取和修改isHave属性。

其中默认有一个无参构造方法,可以省略不写。

二、刘小爱

创建一个刘小爱类,以实现Runnable接口的方法来创建刘小爱线程:

①刘小爱类中有一个包子对象。

②设定构造方法(baozi)。

同时重写run方法,设定一个while死循环,毕竟有包子的话刘小爱就会不停地吃。

③锁对象:保证对象唯一。

因为刘小爱在吃包子的时候,包子铺不能进来干涉,这是一开始的设定,所以需要设定一个锁。

④if判断语句:如果为真,表示有包子。

那么刘小爱就吃包子,并打印输出。

⑤setIsHave方法和notify()方法:

setIsHave方法:刘小爱将包子吃完了,包子没了,将isHave设定为false。

notify方法是Object类里的一个方法,Obeject是所有类的顶层父类,也就是说所有对象都自带这个方法。

notify方法:唤醒此对象监视器上的其他未进来的线程。

什么意思呢?就是将另一个线程(也就是包子铺线程)唤醒。

⑥if判断语句:如果不为真,表示没有包子。

没有包子,刘小爱就等包子生产好了再吃,进入等待状态。

wait方法和notify方法一样,也是Object类里的一个方法。

wait方法:一个线程进行了规定操作后,就进入等待状态。

三、包子铺

创建一个包子铺类,以实现Runnable接口的方法来创建包子铺线程:

①包子铺中有个baozi对象。

其中设定好构造方法(baozi),并且和刘小爱一样,重写run方法,while死循环。

②锁对象:保证对象唯一。

同样的,包子铺在生产包子的时候,刘小爱不能进来,所以要锁对象。

③if判断语句:如果为真,表示有包子。

那么包子铺要等待包子被吃完,故使用wait方法。

④if判断语句:如果不为真,表示没有包子。

那么包子铺要生产包子,并打印输出。

⑤setIsHave方法和notify方法:

现在包子铺生产好包子了,那么包子铺要将isHave设定为true,并将刘小爱唤醒。

四、测试

现在类都创建好了,开始测试:

①创建包子对象。

②创建刘小爱和包子铺对象。

用包子对象给他们初始化赋值,注意要保证它们为同一个包子对象。

③创建两个线程。

分别给线程初始化赋值:一个为包子铺线程,一个为刘小爱线程。

④将这两个线程启动。

现在代码都写好了,最后看看代码执行后的效果:

包子铺生产包子,刘小爱吃包子,两个线程互相合作依次进行。

以上就是刘小爱去包子铺吃包子的案例。

这个案例对应了Java线程中的生产者消费者模式,该例子在逻辑上并不算太缜密,不过相对而言更好理解。

生产者对应谁?

包子铺在生产包子,自然它就是生产者;

消费者对应谁?

刘小爱在吃包子,自然它就是消费者。

生产者消费者模式在面试中有可能会被面试官问到,所以最好要将其理解,不过不要说什么刘小爱去包子铺吃包子的案例,面试官听不懂的。

面试官可不知道什么包子铺,更不知道什么刘小爱,要说生产者和消费者。

总结:

本文分享自微信公众号 - 刘小爱(liuxiaoai946)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

以上是 【Java】基础34:线程之间的合作? 的全部内容, 来源链接: utcz.com/z/508827.html

回到顶部