同步问题-旋锁模式

下午在写计算机网络作业---一个WebServer(基于HTTP/1.0协议)
打算用线程池来实现 虽然实现了线程池,但是觉得很chuo(很烂),MayBe功能还不如来一个请求开一个线程,先不说这个,但是里面遇到的一个同步控制问题,让我迷惑了一阵子,最后查阅了Practical Java才明白了所以然,其实也就是一个旋锁模式(spin-lock pattern)觉得有必要写下来,如下:
......
synchronized(controller){
if (condition == null){
   try{
       condition.wait();
   } catch(Exceptione ){}
......
condition = null;
}
假设有两个线程需要运行这段代码,如果当condition满足的时候,一个线程抢到了锁,并向后面执行,并将condition赋值为null;如果这时候恰好通过notify唤醒了所有在condition上面等待的线程,则就不会再测试condition是否为null,而是从刚刚执行的condition.wait()后面开始执行,这样就会出现错误,因为codition现在已经是null了。所以应该改成这样:
......
synchronized(controller){
while (condition == null){
   try{
       condition.wait();
   } catch(Exceptione ){}
......
condition = null;
}
用循环,迫使其需要使用condition的线程反复测试,确保其正真获得其锁并执行时候codition是非空的
如果觉得还不清楚的可以去看侯捷翻译的那本Practical Java的中文版中的时间54:针对:wait()和notifyAll()使用旋锁(spain locks) 上面说得非常清楚
上面的错误在平时看来很容易发现,但是在具体用到同步操作时候(尤其是像我这种初学者^^),很容易犯,所以记下来,供自己和别人参考。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值