- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
线程通信参考
在上面的学习中,我们了解了在多线程编程的过程中使用同步机制的重要性,并学会了
如何实现同步的方法来正确地共享资源。这些线程之间是相互独立的,并不存在任何的
依赖关系。他们各自竞争CPU资源,互不相让,并且还无条件的其他线程对共享资源
的异步。然而,也有很多的现实问题要求不仅要同步的同一共享的资源,而且线程
间还彼此牵制,通过相互通信来向前运行。
比如说经典的生产者和消费者问题。这个问题呢描述了这样一种情况,假设仓库中只能
存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走消费。如果仓
库中没有产品,则生产者可以将产品放入仓库,否则停止生产并等待,直到仓库中的产品被
消费者取走为止。如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等
待,直到仓库中再次放入产品为止。
很显然这是一个线程同步的问题,生产者和消费者共享同一个资源,并且生产者和消费
者之间是相互依赖的,而且它们互为条件。那么我们如何编写程序来解决这个问题呢?
传统的思路是利用循环检测的方式来实现。这种方式通过重复检查某一个特定的条件是
否成立来决定线程的推进顺序。比如,一旦生产者生产结束,它就利用循环检测来判断仓库
中的产品是否被消费者消费,而消费者也是在消费结束后就会立即使用循环检测的方式来判断
仓库中是否又被放进产品。显然这种实现方法是非常消耗CPU资源的,不值得提倡。那么
有没有更好的方法来解决这类问题呢?
首先,当一个线程在继续执行前需要等待一个条件方可继续执行时,仅有synchronized关
键字是不够的。因为虽然synchronized关键字可以并发更新同一个共享资源,实现了同
步,但是它不能用来实现不同线程之间的消息传递,也就是所谓的通信。而在处理此类问题
的时候又必须要遵守一种原则。即:对于生产者,在生产者没有生产产品之前,要消费
者等待。而在生产了产品呢,又需要马上消费者消费。对于消费者,在消费者消费
,要生产者已经消费结束,需要继续生产新的产品以供消费。
其实,Java了3个非常重要的方法来巧妙的解决线程之间的通信问题。这三个方法
分别是:wait()方法、notify()方法和notifyAll()方法。这三个方法都是在Object类中定义的。
而我们知道所有的Java类都是Object的子类,因此,每个类都默认的拥有它们。但是大家
要注意这三个方法都只能在同步方法或者同步代码块中使用,否则会抛出异常。
首先我们先看一下wait()方法。调用wait()方法,会挂起当前线程,并释放共享资源的
锁,然后从运行态,进入等待队列,直到调用了wait方法所属的那个对象的notify()方
法或者notifyAll()方法为止。
下面我们看一下另外的一个方法,notify()方法。调用notify()方法可以因为调用wait
方法而被挂起的线程。并使这个线程等待队列,进入可运行状态。如果此时没有等待的
线程,此方法就什么都不做。
notifyAll()方法,调用了notifyAll()方法,可以使所有因为调用wait方法而被挂起
的线程都重新启动,但是有一个条件,那就是wait方法和notifyAll方法属于同一个对象。
此时,优先级最高的那个线程最先执行。
显然,利用这些方法,我们就不必再循环检测共享资源的状态,而是在需要的时候直接
等待队列中的线程就可以了。这样不但节省了宝贵的CPU资源,也提高了程序的效率。
那么,到底如何利用这些方法实现线程间的通信呢?下面我们就通过多线程同步的模
型:生产者和消费者的问题来说明怎样通过程序解决多线程间的通信问题。
在这个实例当中,我们可以把生产者和消费者看做是两个线程。而生产和消费的产品可
以看做是共享的资源。因此我们首先定义一个产品类,大家看这段代码。
文档评论(0)