我正在研究 BTree ,我想同步但问题是:
我不想同步整个方法,因为它具有复杂的功能。
我的问题是:如何防止前两个或三个线程传递root==null
的第一个条件?
public void add(TrackingDevice device) {
// Tree is Empty, then add a new elemet to root
if (root == null ) {
root = new BTreeNode(true);
root.keys[0] = device;
root.n++;
} else {
/*
* The root is Full
*/
if (root.n == 2 * t - 1) {
splitRoot();
root.insert(device);
height++;
} else {
root.insert(device);
}
}
}
答案 0 :(得分:1)
我会使用std::replace及其compareAndSet方法。
然后多个线程可以传递条件root.get()== null并创建根节点。但只有最快的线程才会通过compareAndSet写入值。
答案 1 :(得分:0)
我只是建议:实现类似信号量的结构。定义一个同步计数器,你的线程每次进入时都会递减(注意:这个操作必须是互斥的)并且如果counter == 0,则阻止线程进入一个部分。
答案 2 :(得分:0)
您可以使用AtomicReference<BTreeNode>
来引用根节点,并使用compareAndSet(null, new BTreeNode(true))
来阻止if
块的进入。如果非常频繁地调用add
方法,则此方法最终会创建许多短暂的BTreeNode
实例。如果这是一个问题,您可以先“手动”检查AtomicReference
是否包含null
,并且只有这样才能调用compareAndSet
。
但是,我会彻底摆脱null
检查,并最初设置一个带n = 0
的根节点。这使得代码更加统一,因为不需要检查根是否存在。