任务不仅是只有竞争的关系,还有协作。所谓的协作,就是一般意义上的协作,多个任务同时完成同一个问题的各个部分。所以,现在问题已经不是任务间的干涉,而是任务间的协调。因为在这类问题中,某些部分必须在其他部分被解决前解决,而且,在这些任务中,某些是可以并发执行的。某些甚至是所有任务都结束后进行,就像建房子一样,总得建完地基后才能开始往上建吧。
所以,任务的协作的关键就是任务间的协议。怎样才能实现这种协议呢?还是使用互斥,也就是锁。没错,你没有看错,就是使用锁来实现协作。为什么可以呢?明明协作与竞争在字面上来说,应该是相反的啊,但是基本构成是可以一样的啊。因为锁能够确保只有一个任务可以响应某个信号,就是可以消除任何可能的竞争,在这样的基础上,我们就可以将任务自身挂起,直到某个外部条件发生变化,表示是时候让这个任务开工了。这样的实现是由Object的wait()和notify()来完成的。
wait()可以使我们等待某个条件发生变化,而改变这个条件超出了当前方法的控制能力。通常,这种条件由另一个任务来改变。但是,这里要注意,不能让你的这个任务陷入忙等待中,就是在测试这个条件时,不断进行空循环。因此,wait()会将这个任务挂起,只有在notify()或notifyAll()发生时,即发生了唤醒条件,这个任务就会被唤醒并且去检查这个条件。在任务的加锁机制这部分,我们知道,调用sleep()和yield()时,锁并没有被释放,但是wait()却大大不同,它会释放锁,这就使得其他synchronized方法可以获得该锁。这就是为什么利用锁就可以达到热任务的协作的关键,因为wait()方法不仅挂起线程,而且释放锁,然后等到notify()或notifyAll()捕捉住唤醒条件,开始执行下一步。我们在使用wait()时,习惯用法就是用一个检查唤醒条件的while循环来包围wait()。这点是非常重要的,为什么呢?原因有下面几个方面:
1.我们可能有多个任务出于相同的原因在等待同一个锁,而第一个唤醒任务可能会改变这种状况,那么这时我们应该怎么做呢?就是将这个任务挂起,防止其造成这种现象,因为它只需要执行到它满足唤醒条件时该做的事情就行,其他的事情不需要现在做,自然会有其他唤醒条件,所以,这个循环就能使得当它完成工作时被挂起;
2.在这个任务从其wait()中被唤醒的时刻,有可能会有某个其他的任务已经做出了改变,从而使得这个任务在此时不能执行,或者执行其操作已显得无关紧要,所以必须时时检查唤醒条件,在这情况下就应该马上挂起;
3.可能某些任务出于不同的唤醒条件在等待你的对象上的锁,这时就要看看唤醒条件是否已经改变,如果改变,就应该挂起释放锁,而且,注意,这时应该是使用notifyAll()。
当然,只要有认真看完上面的内容的,就会产生一个疑问,就是notify()和notifyAll()有什么区别?notifyAll()正如它后面的all,表示唤醒所有正在等待的任务,这句话是不完整的,真正的意思是,它可以唤醒所有等待调用notifyAll()的任务所持有的锁的任务。那么什么时候该使用notify(),什么时候该使用notifyAll()呢?一般情况下,使用notify()而不是notifyAll()是一种优化,因为不用唤醒所有任务,但是我们必须保证一点,就是我们唤醒的是正确的任务,可是啊,如果有多个任务在等待不同的条件,我们又怎能知道我们唤醒的是正确的任务?因为使用notify()只能唤醒一个任务!所以如果无法保证我们唤醒的是一个正确的任务,那么请选择notifyAll(),就像上面第三条所说的情况,你要唤醒的是唤醒条件不同的各个任务,那么就一起唤醒吧。

任务的协作的基本实现相关推荐

  1. 协作是企业管理的重点和难点

    这个问题让我想起了一道数学题,1+1=?.在生活中这个题目的答案会千差万别,更别说一个企业.在我眼中,企业中最难管的是关系,更准确的说是协作. 经理过好几个信息系统建设的项目,小到一个简单的邮件系统, ...

  2. Git Flow—Git团队协作最佳实践

    一.规范的Git使用 Git是一个很好的版本管理工具,不过相比于传统的版本管理工具,学习成本比较高. 实际开发中,如果团队成员比较多,开发迭代频繁,对Git的应用比较混乱,会产生很多不必要的冲突或者代 ...

  3. Servlet基础:接口、类、请求响应、配置、会话追踪、上下文、协作、异常

    10.1 Servlet介绍 ​ Servlet技术是Sun公司提供的一种实现动态网页的解决方案,它是基于Java编程语言的Web服务器端编程技术,主要用于在Web服务器端获得客户端的访问请求信息和动 ...

  4. java多线程三之线程协作与通信实例

    多线程的难点主要就是多线程通信协作这一块了,前面笔记二中提到了常见的同步方法,这里主要是进行实例学习了,今天总结了一下3个实例: 1.银行存款与提款多线程实现,使用Lock锁和条件Condition. ...

  5. 打造一流创新环境:协作、开放、可持续

    作者 | 微软亚洲研究院院长 周礼栋 毋庸置疑,人类是群居物种.早在两千多年前,亚里士多德便在其著述<政治学>里揭示了人类群居共利协作的趋向:个体组成家庭,家庭组成村落,村落组成城池,城池 ...

  6. 制造业智能化的下一站——人与机器的协作

    作者:联想之星 Comet Labs 美国运营合伙人 Lucas 工业4.0.智能制造.机械手臂.各式传感器--近年来,当人们在谈论到生产制造智能化时,经常会提到以上这些概念.有些人甚至还会直接讨论到 ...

  7. 如何团队协作,代码托管?Git使用教程:最详细、最浅显、一文读懂Git常用操作!...

    点击上方"Datawhale",选择"星标"公众号 第一时间获取价值内容 作者:涂根华 来源:www.cnblogs.com/tugenhua0707 Git使 ...

  8. Colab不好用,有人花两年开发了一个新notebook,支持实时协作还更快

    机器之心报道 机器之心编辑部 工具不好用就自己开发一个,「不将就」的开发者就是这么任性. 市场上现有的数据科学 notebook 工具都有很多痛点,比如版本控制.可复现性.协作体验等,与其他工具配合使 ...

  9. 关于协作机器人10个观点的讨论

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 在当今的加工设备中,自动化应用往往需要功能强大的机器人.也就是说, ...

  10. 用于语义分割的特征共享协作网络

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 论文是学术研究的精华和未来发展的明灯.小白决心每天为大家带来经典或 ...

最新文章

  1. 在ASP.NET中获取文件属性
  2. 解决Clover在win 10下的兼容问题
  3. LaTeX中警告类型及说明
  4. C指针原理(20)-C指针基础
  5. 电脑卡顿不流畅是什么原因_为什么安卓系统用久了会卡,苹果系统却依然流畅?原因找到了!...
  6. 通过jQuery EasyUI实现基本的拖放,此为转发!!大家学习讨论
  7. Iterables和迭代器
  8. redis实战之事务与持久化
  9. 图文实例带你了解香农编码和霍夫曼编码
  10. 通俗理解逻辑删除和物理删除的区别
  11. 刽子手c语言,古代神秘职业:刽子手的祖师爷
  12. 学习网站及工具地址汇总
  13. base64-图片传输
  14. 小米MIX 2还没上一代震撼,为什么却说雷军更自信了?
  15. 【计算机毕业设计】外卖点餐源码
  16. Spread / Reast 操作符(...arr / ...obj)
  17. 如何将Python打包后的exe还原成.py?
  18. 性能优化之内存泄露(Memory Leak)常用分析工具(另3种)
  19. L2-3 清点代码库【STL】
  20. php 的单例模式(一)

热门文章

  1. PHP过滤器 filter_has_var() 函数
  2. ABP入门系列(7)——分页实现
  3. android studio运行时报错the selected device is incompatible
  4. Google Maps Android API v2官网例子使用说明
  5. 忘记MySQL密码怎么办
  6. 【QwQ】乱七八糟的置顶
  7. redis企业级应用(下)-如何维护redis的key
  8. 中小型研发团队架构实践:高效率、低风险,一键发布并测试的持续集成工具Jenkins...
  9. Spring源代码解析(收藏)
  10. 百度地图应用开发(一)