如果我在通过Collections.unmodifiableSet()运行它后有一个HashSet实例,它是否是线程安全的?
我问这个,因为Set文档声明它不是,但我只是执行读操作.
例如,我需要类似的东西:
Collection<String> collection = /* ... */;
Stream<Object> stream = /* ... */;
boolean containsAll = stream.map(Object::toString).containsAll(collection);
Run Code Online (Sandbox Code Playgroud)
当然,我可以Collection
使用collect()
方法和调用将流的所有元素累积到另一个元素中Collection.containsAll()
,但是如果流太大并且处理所有元素的效率低下怎么办?
想象有一个主线程,它创建一个 HashSet 并启动许多将 HashSet 传递给它们的工作线程。
就像下面的代码一样:
void main() {
final Set<String> set = new HashSet<>();
final ExecutorService threadExecutor =
Executors.newFixedThreadPool(10);
threadExecutor.submit(() -> doJob(set));
}
void doJob(final Set<String> pSet) {
// do some stuff
final String x = ... // doesn't matter how we received the value.
if (!pSet.contains(x)) {
synchronized (pSet) {
// double check to prevent multiple adds within different threads
if (!pSet.contains(x)) {
// do some exclusive work with x.
pSet.add(x);
}
}
}
// do some stuff …
Run Code Online (Sandbox Code Playgroud) 我有 2 个 Main 类的内部线程类。有时,当一个添加新元素而另一个被删除时,它会导致 ConcurrentModificationException。我想我不知道如何同步它们。
Class Main{
HashSet<MyObject> set;
Thread A{
run(running){
...
set.add(obj);
...
}
}
Thread B{
run(){
while (running) {
for (Iterator<MyObject> i = set.iterator(); i.hasNext();) {
MyObject obj= i.next();
if (!obj.isSmt()) {
i.remove();
...
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 我需要有键值对,其中值可以是一组。此数据结构应该是线程安全的,以便在多线程环境中将删除元素添加到集合中。
我的要求是创建一个订阅列表,在这里人们可以订阅不同的主题。这个订阅列表应该是并发的、线程安全的、快速的。我正在考虑使用 ConcurentHashMap 和 ConcurrentHashSet,这对我没有帮助,因为我必须将同步块放在顶层,它将阻塞整个映射,直到放置/删除操作完成。
我目前正在实施缓存.我已完成基本实现,如下所示.我想要做的是运行一个线程,删除满足特定条件的条目.
class Cache {
int timeLimit = 10; //how long each entry needs to be kept after accessed(marked)
int maxEntries = 10; //maximum number of Entries
HashSet<String> set = new HashSet<String>();
public void add(Entry t){
....
}
public Entry access(String key){
//mark Entry that it has been used
//Since it has been marked, background thread should remove this entry after timeLimit seconds.
return set.get(key);
}
....
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,我应该如何实现后台线程,以便线程绕过集合中的条目并删除已经存在的条目marked && (last access time - now)>timeLimit
?
编辑
上面只是代码的简化版本,我没有写同步语句.
我刚刚阅读并理解了散列如何与HashMap一起使用:它如何使用散列表,使用散列函数制作散列码等.
我的问题是:如果相同的原则适用于HashSet?很明显它无法从HashSet的密钥计算哈希码,因为它没有哈希码.但它是否从HashSet的值计算哈希码呢?
我已经知道当我们有Key-Value对时我们使用HashMap,而当我们不需要重复数据时我们使用HashSet.但是我总是对Hashtable发挥作用感到困惑.它是一个完全不同的数据结构吗?或者HashMap和HashSet都使用哈希函数在Hashtable中存储数据?彻底的解释将非常有用.
java ×8
hashset ×3
concurrency ×2
hashmap ×2
collections ×1
contains ×1
hash ×1
hashtable ×1
java-8 ×1
java-stream ×1