在 Java 中锁定哈希集

发布于 2024-09-26 20:22:35 字数 120 浏览 0 评论 0原文

我的代码中有一个对象引用的静态 HashSet,它必须禁止所有写入请求,直到给定的方法正在运行(该方法仅将哈希集用于读取目的)。我已阅读 Thread 基础知识,但尚不清楚如何继续执行此操作。

有人可以帮我吗?

I have a static HashSet of object references in my code, which has to disallow all write requests until a given method is running (which uses the hashset only for read purposes). I have read the Thread basics but am yet not clear how to proceed doing this.

Can anyone please help me out ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ら栖息 2024-10-03 20:22:35

您提到您已经阅读了线程基础知识,因此我假设您有一个多线程应用程序,其中有多个读取器和/或写入器。您可以使用读写锁来限制对集合的访问。当给定的方法执行时,它会锁定读锁,这允许其他人读取,但不允许写入。只要您使用下面的 putInSet 方法(或类似的方法)进行写入,就可以要求写入锁进行写入。然后,在持有读锁时,无法写入该集合。

private final Set<Object> mySet = new HashSet<Object>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void methodThatRunsAndAllowsReadOnly() {
    lock.readLock().lock();
    try {
        // method body here
    }
    finally {
       lock.readLock().unlock();
    }
}

public void putInSet(Object o) {
    lock.writeLock().lock();
    try {
        mySet.add(o);
    }
    finally {
       lock.writeLock().unlock();
    }
 }

You mentioned that you have read the Thread basics, so I assume you have a multi-threaded app where you have multiple readers and/or writers to the set. You could use a read-write lock to restrict access to the collection. When the given method executes, it locks the read lock, which allows others to read, but not to write. As long as you write using the putInSet method (or something similar) below, you can require the write lock to write to. Then the set cannot be written to while the read lock is being held.

private final Set<Object> mySet = new HashSet<Object>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void methodThatRunsAndAllowsReadOnly() {
    lock.readLock().lock();
    try {
        // method body here
    }
    finally {
       lock.readLock().unlock();
    }
}

public void putInSet(Object o) {
    lock.writeLock().lock();
    try {
        mySet.add(o);
    }
    finally {
       lock.writeLock().unlock();
    }
 }
痴骨ら 2024-10-03 20:22:35

您可以使用Collections.unmodifyingSet 创建集合的只读视图。只需将此视图传递给不需要写入集合的每个人即可。 (任何试图修改此视图的人都会抛出UnsupportedOperationException。)

You can create a read-only view of the set by using Collections.unmodifiableSet. Just pass this view to everyone who doesn't need to write to the set. (An UnsupportedOperationException will be thrown for anybody who tries to modify this view.)

青衫儰鉨ミ守葔 2024-10-03 20:22:35

这是一个有趣的问题,通常情况是相反的。

如果您想要一个不可变的映射,直到某种神奇的方法告诉应用程序的其余部分可以使用Collections.unmodifyingMap()在初始化后创建映射的不可变副本。

当魔术方法运行时,它可以再次用可修改的副本替换地图。

Map myMap;

public MyClass(Map myMap) {
    this.myMap = Collections.unmodifiableMap(myMap);
}

synchronized public void releaseMyMap() {
    myMap = new HashMap(myMap);
}

This is an interesting question, normally it is the other way around.

If you want an immutable map till some magic method tells the rest of the application that it is ok you can use Collections.unmodifiableMap() to create an Immutable copy of your map after initialisation.

When the magic method runs, it can replace the map with a modifiable copy again.

Map myMap;

public MyClass(Map myMap) {
    this.myMap = Collections.unmodifiableMap(myMap);
}

synchronized public void releaseMyMap() {
    myMap = new HashMap(myMap);
}
玩心态 2024-10-03 20:22:35

您可以从 Set 进行扩展并提供您自己的基于锁的实现(添加)来读取和写入 Set。

这将确保每当一个线程正在读取时(在获取锁之后),其他线程都无法对其进行写入。

You can extend from a Set and provide your own lock based implementation (of add) to read and write to the Set.

This will ensure that whenever a thread is reading (after acquiring the lock) no other thread can write to it.

梦行七里 2024-10-03 20:22:35

不完全确定问题是什么,但如果您只是想避免访问 HashSet 时出现并发问题,可能值得看看 ConcurrentSkipListSet。大多数操作需要 log(n) 时间,但它不需要同步,也不会阻塞插入、删除和访问操作。总的来说,这可能会给你带来更好的表现。

No exactly sure what is the problem, but if you are just trying to avoid concurrency issues with access to with HashSet, probably worth looking at ConcurrentSkipListSet. It takes log(n) time for the most of operations, but it doesn't require synchronization and doesn't block on insertion, removal, and access operations. In the whole that may give you better performance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文