关于SO的一些答案提到HashMap中的get方法可以落入无限循环(例如这一个或这个),如果没有正确同步(通常底线是"不要在多线程中使用HashMap")环境,使用ConcurrentHashMap").
虽然我可以很容易地看到为什么对HashMap.put(Object)方法的并发调用会导致无限循环的原因,但是当我尝试读取正在调整大小的HashMap时,我无法理解为什么get(Object)方法会被卡住那一刻.我看一下openjdk中的实现,它包含一个循环,但退出条件e != null迟早应该完成.它怎么能永远循环?明确提到易受此问题影响的一段代码是:
public class MyCache {
private Map<String,Object> map = new HashMap<String,Object>();
public synchronized void put(String key, Object value){
map.put(key,value);
}
public Object get(String key){
// can cause in an infinite loop in some JDKs!!
return map.get(key);
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释一个线程如何将一个对象放入HashMap,另一个读取它是否可以交错以产生无限循环?它是否与某些缓存一致性问题或CPU指令重新排序有关(所以问题只能在多处理器机器上发生)?
基于本答案末尾的注释,看起来子类型和继承是Java中略有不同的概念.它是什么?仅当类声明包含extends ...子句时才继承吗?如果是这种情况,那么一个类不会从Object继承,即使它是它的子类型,对吧?
在python中,内置函数是tuple([iterable])创建一个元组对象并用“iterable”元素的副本填充它,还是创建一个包含对“iterable”已经存在的对象的引用的元组?
我有这段代码:
#include<iostream>
#include<vector>
class A
{
private:
static int x;
public:
A(){}
~A()
{
++x;
std::cout << "destroying A " << x << std::endl;
}
};
int A::x(0);
int main (int args, char** argv)
{
std::vector<A> vectA(5);
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我希望它打印5行(即为向量中的5个元素中的每一个调用析构函数)但实际上输出是:
destroying A 1
destroying A 2
destroying A 3
destroying A 4
destroying A 5
destroying A 6
Run Code Online (Sandbox Code Playgroud)
嗯奇怪......
所以我将主要功能更改为:
int main (int args, char** argv)
{
std::vector<A> vectA(5);
std::cout << vectA.capacity() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
现在的输出是:
destroying A 1
5
destroying …Run Code Online (Sandbox Code Playgroud) 我不明白为什么这段代码会编译:
#include <set>
#include <list>
#include <algorithm>
int modify(int i)
{
return 2*i;
}
int main (int args, char** argv)
{
std::set<int> a;
a.insert(1);
a.insert(2);
a.insert(3);
std::list<int> b; // change to set here
std::transform(a.begin(), a.end(), b.begin(), modify); // line 19
}
Run Code Online (Sandbox Code Playgroud)
同时,如果我只是将 b 的类型从 更改为std::list<int>,std::set<int>它会在编译时(第 19 行)失败并显示错误:read-only variable is not assignmentable。要将 b 用作集合,我需要将变换线更改为
std::transform(a.begin(), a.end(), std::inserter(b, b.begin()), modify);
Run Code Online (Sandbox Code Playgroud)
这是为什么?我以某种方式猜测原因与 set 是一个关联容器而 list 是一个序列容器这一事实有关,但我在这里可能完全偏离了重点。
我忘了提及:我使用默认标准 (c++98) 在 gcc 3.4.2 和 llvm 3.3 上尝试过这个。我使用 c++03 …