论坛首页 Java企业应用论坛

java并发线程-----阻塞队列的实现和思考

浏览 17453 次
精华帖 (3) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (6)
作者 正文
   发表时间:2011-07-06  
看到N个对象锁,
就没兴趣了
0 请登录后投票
   发表时间:2011-07-06  
AngelAndAngel 写道
snake1987 写道
看起来像刚学习java的synchronized的时候做的事情~~
不过这句很经典:
“如果没有任务会阻塞,那么单处理器机器上使用并发就没有任何意义。”也就是用并发的本质原因

 
  因为看到过多个对象锁实现功能,但总觉得死锁不可避免 兄弟留下的痕迹太少了 我看不出对这个问题有好的回答。还有我觉得任何简单的程序都有最佳实践 对么,估计这方面你应该了解比较深入,能否把你的心得体会写出来。


首先,死锁的根本原因在于反向加锁,也就是说锁A,锁B,锁C,这三个步骤如果永远都是按照这个顺序加锁的话,是不会有死锁问题的,如果任一个人误用你设计的锁逻辑,有锁B,锁A,或者锁C,锁A或者锁C,锁B这样的调用链的存在, 就会出现死锁了

也就是说,如果你控制了加锁的顺序,是不会产生死锁的

但你用一个api的时候,编译器是不会告诉你:这个方法锁住了A(有时候,锁的对象还是动态变化(动态死锁)的,如:trade(A,B){lock(A){lock(B)}},A跟B到底对应的是哪一个对象,是在运行期变化的,这样的情况我们需要加锁前做一个排序),所以在我们设计的时候,通常很难注意到死锁问题,但跑起来就死锁就不可避免地出现了

之前看的一本书介绍了几种方法:
1.open call,也就是你需要加锁,并且在锁范围内,需要调用另一个api的时候,你要确认,你调用的方法没有加锁,这样,你在自己的方法内就可以完全控制加锁的顺序了
2.之前说的,动态死锁,你要根据一定的规则对传入的对象进行一个排序

snake1987 写道

不过这句很经典:
“如果没有任务会阻塞,那么单处理器机器上使用并发就没有任何意义。”也就是用并发的本质原因


之所以我说这句经典,是之前我自己也犯过一个思想上的错误:为了并发而用并发
并发跟单线程的效率的区别在哪?当A线程阻塞的时候,B线程可以在阻塞的期间帮你推进任务的完成

当你需要用线程的时候,你多问问自己,你这个调用逻辑有会阻塞的步骤吗?

以上只是我自己的一些片面的想法,可能某些地方还是有些逻辑上的片面性,还请tx们多多指教,呵呵
0 请登录后投票
   发表时间:2011-07-06  
xyfwjk 写道
为什么生产工发现仓库没有物品了会去唤醒搬运工,,,,而不是放完产品后再唤醒呢

有道理 同问
0 请登录后投票
   发表时间:2011-07-06  
zhangbenben 写道
xyfwjk 写道
为什么生产工发现仓库没有物品了会去唤醒搬运工,,,,而不是放完产品后再唤醒呢

有道理 同问

只要唤醒就可以了 前后无所谓 只要同步块没出来 即使提前唤醒了 对方没得到锁 也不能立即执行。不过我放这里确实容易让人误解,看着也不太合适,呵呵。
0 请登录后投票
   发表时间:2011-07-06  
AngelAndAngel 写道
zhangbenben 写道
xyfwjk 写道
为什么生产工发现仓库没有物品了会去唤醒搬运工,,,,而不是放完产品后再唤醒呢

有道理 同问

只要唤醒就可以了 前后无所谓 只要同步块没出来 即使提前唤醒了 对方没得到锁 也不能立即执行。不过我放这里确实容易让人误解,看着也不太合适,呵呵。

linkedList 用volatile 修饰不行吗? 这样也保持了同步。
0 请登录后投票
   发表时间:2011-07-06  
zhangbenben 写道
AngelAndAngel 写道
zhangbenben 写道
xyfwjk 写道
为什么生产工发现仓库没有物品了会去唤醒搬运工,,,,而不是放完产品后再唤醒呢

有道理 同问

只要唤醒就可以了 前后无所谓 只要同步块没出来 即使提前唤醒了 对方没得到锁 也不能立即执行。不过我放这里确实容易让人误解,看着也不太合适,呵呵。

linkedList 用volatile 修饰不行吗? 这样也保持了同步。

现在的目的是需要程序通过阻塞和协调来完成队列功能,而不是利用volatile不造成阻塞,举个例子,就好比ThreadLocal是用来存储当前线程变量 而不是为了实现并发线程一样。
0 请登录后投票
   发表时间:2011-07-06  
AngelAndAngel 写道
zhangbenben 写道
AngelAndAngel 写道
zhangbenben 写道
xyfwjk 写道
为什么生产工发现仓库没有物品了会去唤醒搬运工,,,,而不是放完产品后再唤醒呢

有道理 同问

只要唤醒就可以了 前后无所谓 只要同步块没出来 即使提前唤醒了 对方没得到锁 也不能立即执行。不过我放这里确实容易让人误解,看着也不太合适,呵呵。

linkedList 用volatile 修饰不行吗? 这样也保持了同步。

现在的目的是需要程序通过阻塞和协调来完成队列功能,而不是利用volatile不造成阻塞,举个例子,就好比ThreadLocal是用来存储当前线程变量 而不是为了实现并发线程一样。

你对线程池 和线程心跳时间 了解吗?请教您
0 请登录后投票
   发表时间:2011-07-06  
为什么不使用Jdk内置的阻塞队列,而要重复发明轮子,而且也不见得会比内置的好,要想了解怎么实现,直接看源码或者学习下java并发知识就好了
0 请登录后投票
   发表时间:2011-07-06   最后修改:2011-07-06
kolor 写道
为什么不使用Jdk内置的阻塞队列,而要重复发明轮子,而且也不见得会比内置的好,要想了解怎么实现,直接看源码或者学习下java并发知识就好了

内置的确实功能完善  期待兄弟上一篇源码解读 谢谢
0 请登录后投票
   发表时间:2011-07-07  
volatile 只保证可见性,不能保证原子性

"在那些非原子且可由多个线程访问的易变操作中,一定不能够依赖于 volatile 的同步机制,相反,要使用 java.util.concurrent 包的同步语句、锁类和原子类。它们在设计上能够保证程序是线程安全的。"
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics