多线程数据加锁

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才能解决问题?
...全文
99 点赞 收藏 4
写回复
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
回复 点赞
发动态
发帖子
Java SE
创建于2007-09-28

3.4w+

社区成员

30.7w+

社区内容

Java 2 Standard Edition
社区公告
暂无公告