博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
防止信号的错失
阅读量:6453 次
发布时间:2019-06-23

本文共 1375 字,大约阅读时间需要 4 分钟。

     

 在任务的协作中,是需要任务间的协议,而这份协议,正如之前所说的,正是通过锁来实现。但是,有时候,这协议会错失,就是没有被其他任务正确的接收到。信号的错失会导致错误,所以,我们要为避免信号错失而做出努力,因为信号的错失是可能导致出现死锁的,只要是使用锁,就要避免出现死锁这种局面。这问题的解决方案就是防止在唤醒条件上产生竞争,因为很多时候的错失都是因为对唤醒条件的竞争,如:
T1:
       synchronized(sharedMonitor){
           <setup condition for T2>
            sharedMonitor.notify();
        }
     
T2:
    while(someCondition){
         synchronized(sharedMonitor){
            sharedMonitor.wait();
         }
    }
         <setup condition for T2>是防止T2 调用wait()的一个动作,当然前提是T2还没有调用wait()。这个的具体实现可以不用管。假设T2对someCondition求值并发现其为true,在T2中的while循环中,线程调度器可能切换到T1,而T1将执行其设置,然后调用notify(),当T2得以继续执行时,此时对于T2来说,时机已经太晚了,以至于不能意识到这个条件已经发生变化,因此会盲目进入wait(),此时notify()将错失,而T2也将无限的等待这个已经发送过的信号,从而产生死锁。大家可能还是对这个<setup condition for T2>的具体实现有疑问,到底怎么实现,其实我们可以这样想,因为线程调度机制到底怎么处理,我们并不清楚,所以实际处理中是可能会出现上面的情况,就算我们并没有什么特别的举动。解决的做法很简单,简单到只需调换一下顺序就行。就是这样:
       synchronized(sharedMonitor){
           while(someCondition){
                sharedMonitor.wait();
            }
       }
      为什么这样就可以消除对唤醒条件的竞争呢?因为现在当T1首先执行时,当控制返回T2时,它将发现条件发生变化,从而不会进入wait(),反过来,如果T2首先执行,那它将进行wait(),并且稍后会由T1唤醒。
        好了,前面都是《Thinking in java》中的内容,是的,其实基本上都是一样的,之所以这样贴出来,是想要和大家一起探讨这部分的内容。这时,我们都会有一个疑问,时机,那个错失的时机到底在哪?两个代码的区别就在于唤醒条件的出现顺序。让我们顺着这样说下去,前面所讲的,在T2中的while循环中,线程调度器可能切换到T1,这完全是有可能的,因为T1根本就没有唤醒条件,所以它是可以进行的,而这个T1中恰好有防止T2调用wait()的动作,所以T2可能就无法在这个本该唤醒的时候没有唤醒,等到T1调用notify()唤醒的时候就可能有点晚了。这就是信号的错失。那么现在呢,T1先执行,使得唤醒条件发生变化,于是也就不会进入wait()。大家注意到没有,关键就是T1的执行能够对T2的影响是发生在哪个部分,一旦进入方法里面,是不可能会有其他的任务在执行,所以这就能确保信号不会错失。
       所以,大家是否意识到,合理的循环结构是会对我们的程序产生多么大的影响啊,所以设计循环时是要谨慎的。

转载地址:http://apyzo.baihongyu.com/

你可能感兴趣的文章
BZOJ1911:[Apio2010]特别行动队——题解
查看>>
14:开发脚本入侵检测与报警案例
查看>>
python 重要模块
查看>>
单词王(kingWord)
查看>>
javascript数据变量类型判断(JS变量是否是数组,是否是函数的判断)
查看>>
css知多少(9)——float下篇(转)
查看>>
JavaScript中科学计数法转化为数值字符串形式
查看>>
thrift语法
查看>>
杀死进程
查看>>
Kafka之生产者消费者示例
查看>>
CMS:文章管理之模型和Store
查看>>
【FTP】java FTPClient 文件上传内容为空,文件大小为0
查看>>
新项目经理必读:分析什么是项目经理
查看>>
微信“摇一摇&#183;周边”正式开放
查看>>
java jdbc与odbc数据库的连接mysql数据库
查看>>
jQuery(3)
查看>>
android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序
查看>>
第六章例题、心得及问题。
查看>>
iphone xcode 错误提示 Xcode encountered an internal logic error.
查看>>
lsyncd —— 多机器实时同步文件神器
查看>>