Java - 两个线程进入相同的条件并通过

时间:2017-12-17 13:37:15

标签: java multithreading synchronization

我正在研究 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);
        }
    }
}

3 个答案:

答案 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的根节点。这使得代码更加统一,因为不需要检查根是否存在。