全面理解线程间的通信方式_第1页
全面理解线程间的通信方式_第2页
全面理解线程间的通信方式_第3页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、全面理解线程间的通信方式因为存在对共享变量的操作,才有了讨论线程的话题。在线程中存在这样一种场景,一个线程操作了共享变量的值而另一个线程感知了此次操作,然后进行相应的操作。整个过程开始于一个线程,结束与另一个线程。前者我们可以称作生产者,后者我们可以称作消费者,因为有了前者的活动才出发后者逻辑的发生,这种隔离模式在功能实现方面具备了良好的伸缩性。等待通知的java方法是任何对象都具备的,因为这些方法被定义在java的超类java.Iang.Object上下图展示了Object类的所有方法:等待、通知机制就是,线程A调用了对象0的wait()方法进入等待状态,线程B调用了对象0的notify()

2、或者notifyAII()唤醒处于对象0上等待的线程A,使线程A从wait()方法处返回从而进行剩余操作。上述两个线程通过对象0来进行交互,而对象0上的wait()/notify。/notifyAII()就如同信号一般控制着线程的操作。这种例子生活中随处可见,例如商品入库,如果仓库中是满的我们就无法将商品再放入仓库,如果仓库中没有商品我们也无法从仓库中取出商品,再举一个日常发生在我们身边的场景。现在网购越来越方便,我们与快递之间有一个快递小哥在关联,快递小哥将包裹放到快递柜,我们去快递柜领取快递:/*快递*/pubIiccIassCourierextendsThread5SneakyThrow

3、s0verridepubIicvoidrun()9synchronized(CourierCabinet.CABINET)whiIe(true)if(CourierCabinet.CABINET.size()=10)/歇一歇吧快递柜没地方了CourierCabinet.CABINET.wait();CourierCabinet.CABINET.add(包裹);System.out.printIn(亲爱的顾客您的快递已入柜,请及时来领取);CourierCabinet.CABINET.notify();Thread.sIeep(100);20232425/*收件人*/pubIiccIassRec

4、ipientextendsThread56SneakyThrows0verridepubIicvoidrun()10whiIe(true)synchronized(CourierCabinet.CABINET)13if(CourierCabinet.CABINET.size()=0)/快递员还未将包裹入柜没法领取等一等CourierCabinet.CABINET.wait();18CourierCabinet.CABINET.remove(包裹);System.out.printIn(哈哈领到了我的快递.);CourierCabinet.CABINET.notify();Thread.sIee

5、p(100);*快递柜*/pubIiccIassCourierCabinet5/*快递柜容量*/pubIicstaticfinaIListCABINET=newArrayList(10);101112publicstaticvoidmain(Stringargs)131415newThread(newCourier().start();1617newThread(newRecipient().start();19202122运行结果:通过以上例子,可以总结出使用对象的wait()/notify。/notifyAII()所要注意的点:1.调用wait()/notify()/notifyAII()

6、方法的线程必须是持有该对象的锁的线程2调用wait()方法后线程由RUNNING状态变为WAITING状态,并将当前线程放置在该对象的等待队列中,同时释放拥有的锁调用notify()和notifyAII()之后线程并不会立即从wait()方法处返回,而是需要等待调用notify()/notifyAll()的线程释放锁之后才会返回。notify()将等待队列中的线程移动到同步队列中去,notifyAII()将等待队列中所有的线程移动到同步队列中去,此时被移动的线程状态由WAITING转为BLOCKED关于线程同步、通知机制面试题1:为什么操作wait()notify()notifyAll()需要

7、事先获取锁,主要是为了防止死锁了永久等待的发生,以上面的例子说明,收件人线程执行f(CABINET.size()=O)的时候满足条件由于没有synchronize加持,所以该线程并不一定会执行CABINET.wait()可能被CPU切走了,线程进入了BLOCKED状态。此时快递小哥线程获取到了执行权,判断f(CABINET.size=10)不满足条件,然后执行CABINET.add(包裹操作)执行notify()因为收件人线程并没有执行wait(),所以就可能处于一直等待中。就如同你给我打电话我还没有拿到电话你就已经打过了此时我再拿到电话也不会收到你的电话了。Wait()放到synchroni

8、ze中执行就是为了保证线程安全,如果一个线程想要从wait()处返回也需要获取到该对象的锁否则会出现lllegalMonitorStateException异常。2:为什么线程通信的方法wait()notify()notifyAll()是定义在Object中而sleep()定义在线程类中?主要因为java中的wait()notify()notifyAll()都是锁级别的操作,操作这几个方法的线程必须持有该对象的锁,而锁又是属于对象的。每一个对象的对象头中有几位是标识锁的状态的,所以实际上锁是属于对象的并不是属于线程的。如果这几个方法定义在线程中会造成极大的不便,在实际的操作中我们会遇到一个线程获取几把锁的情况,如果将锁定义在线程中时间这种情况就不是那么的方便了。3:wait()方法是属于对象的,那调用Thread.wait()会怎样?调用Thread.wait()也就是说将Thread当做锁对象,持有Thread对象的锁的线程在执行结束后会自动调用notify(),所以我们应该避免使用线程对

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论