java - 关键部分: be sure that this method is executed by only 1 thread

标签 java multithreading concurrency locking critical-section

让事情变得简单: 通常 update() 由多个线程执行。 一旦这是真的 if(!isSplit && users.size() >= Constants.SPLIT_THRESHOLD) 我希望当 split() 函数被单元化时没有人执行 update() 方法。

public class Cell {
    private ConcurrentHashMap<Integer, User> users;
    private ConcurrentHashMap<Long, Cell> subCells;
    private boolean isSplit;
    private Lock splitLock;

    public Set<Integer> update(User user){

        //code executed by 1 thread
        if(!isSplit && users.size() >= Constants.SPLIT_THRESHOLD)
        {
            splitLock.lock();
            {
                try
            {
                    split();
                    isSplit = true;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                finally
                {
                    splitLock.unlock();
                }
            }
        }

        // code executed by multiple threads
        // on users hashmap
    }
    private void merge(){}
    private void split(){}
}

最佳答案

当锁定写入/更新时,一般模式是首先获取锁,然后检查条件(由写入/更新修改),然后写入。

lock
if(x) {
    write/update
}
unlock

与此对比,它类似于您发布的代码:

if(x) {
    lock
    write/update
    unlock
}

对于线程 1,x 可以计算为 true,同时线程 2 执行写入/更新,导致 x 计算为 false,但线程 1 已经在条件内,并且无论如何都会执行写入/更新。失败。

更新:回答更新的问题。

查看 ReentrantReadWriteLock 的 javadoc。

您可能希望使用写锁隔离您的 split() 方法(只有一个线程可以获取),并使用读锁隔离您的 update 方法的其余部分(多个线程可以获取,只要没有人拥有写锁)锁)。

关于java - 关键部分: be sure that this method is executed by only 1 thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18514134/

相关文章:

c# - 如何跟踪 .Net 线程池的使用情况?

node.js - 如何优先考虑快速请求/响应而不是其他密集的服务器相关任务

python - 如何让父线程等待指定的时间或直到子线程完成?

java - 两个线程不同的运行方式并且同时工作

java - Java BitSet 对于并发只读操作线程安全吗

java - 有关服务器客户端游戏的类设计问题

java - FirebaseDatabase仅保存id

java - 将 jdom2 文档转换为 DOMSource

java - Path() - 智能彩色段

java - java在 objective-c 中的并发hashmap的等价物