zoukankan      html  css  js  c++  java
  • 任务的协作的基本实现

         

     任务不仅是只有竞争的关系,还有协作。所谓的协作,就是一般意义上的协作,多个任务同时完成同一个问题的各个部分。所以,现在问题已经不是任务间的干涉,而是任务间的协调。因为在这类问题中,某些部分必须在其他部分被解决前解决,而且,在这些任务中,某些是可以并发执行的。某些甚至是所有任务都结束后进行,就像建房子一样,总得建完地基后才能开始往上建吧。
           所以,任务的协作的关键就是任务间的协议。怎样才能实现这种协议呢?还是使用互斥,也就是锁。没错,你没有看错,就是使用锁来实现协作。为什么可以呢?明明协作与竞争在字面上来说,应该是相反的啊,但是基本构成是可以一样的啊。因为锁能够确保只有一个任务可以响应某个信号,就是可以消除任何可能的竞争,在这样的基础上,我们就可以将任务自身挂起,直到某个外部条件发生变化,表示是时候让这个任务开工了。这样的实现是由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(),就像上面第三条所说的情况,你要唤醒的是唤醒条件不同的各个任务,那么就一起唤醒吧。
  • 相关阅读:
    Centos 7 zabbix 实战应用
    Centos7 Zabbix添加主机、图形、触发器
    Centos7 Zabbix监控部署
    Centos7 Ntp 时间服务器
    Linux 150命令之查看文件及内容处理命令 cat tac less head tail cut
    Kickstart 安装centos7
    Centos7与Centos6的区别
    Linux 150命令之 文件和目录操作命令 chattr lsattr find
    Linux 发展史与vm安装linux centos 6.9
    Linux介绍
  • 原文地址:https://www.cnblogs.com/wenjiang/p/2660540.html
Copyright © 2011-2022 走看看