多线程数据加锁

magicblue 2011-07-07 02:58:14
class B_Factory
{
List<B> bs;
}

class B
{
C c1;
C c2;
}

class C
{
}

class D
{
void f()
{
从A取出B对象,调用B对象的方法去修改c1,c2
同时还有对B_Factory.bs的增加删除操作
}
}

4个类的关系如代码所示意。多线程环境下,D.f()被并发调用。由于B对象是被C对象共享的(2对1),需要在f()加锁。但问题在于,如果在f()里加锁,那么意味着即便可以并发的线程也将被阻塞(比如A.bs里有2个B对象,第一个B对象对应2个C对象,第二个B对象对应另外2个C对象,4个C对象不同。那么当f()操纵的是第一个B对象时,第二的B对象的f()操作完全可以被并发执行,无需等待第一个B对象的操作完成)

我想到的办法是把f()移到B类里去实现,但从代码的角度不太现实,f()里有对B_Factory.bs的增加删除操作,移入B会很麻烦。
或者把f()移到B_Factory,但这和在f()里加锁是一样的,同一时刻,只有一个B对象被操作,即便后面被阻塞的C和现在正在被操作的B完全没关系,也得等着。

从java提供的机制看,似乎只有把f()移入B才能解决问题?
...全文
166 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
magicblue 2011-07-07
  • 打赏
  • 举报
回复
我明白了,在B里加入一个LOCK对象,让D.f()获取此lock对象,然后锁住即可
dyflovexlp 2011-07-07
  • 打赏
  • 举报
回复
你那样锁住的是D对象,实例方法上锁住的是this对象
magicblue 2011-07-07
  • 打赏
  • 举报
回复
有一件事我不太清楚
class D
{
B b;
synchronized void f()
{
从A取出B对象,调用B对象的方法去修改c1,c2
同时还有对B_Factory.bs的增加删除操作
}
}

synchronized 或 ReentrantLock 锁住的是b对象还是B类的所有对象?如果仅仅锁住的是b对象,那么只会阻塞那些和当前获得锁的D.b相同的D对象。
龙四 2011-07-07
  • 打赏
  • 举报
回复
可以用显示的锁ReentranLock和ReentrantReadWriteLock

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧