小编Und*_*ior的帖子

Java HashMap.get(Object)无限循环

关于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 concurrency multithreading hashmap

24
推荐指数
3
解决办法
5487
查看次数

JAVA:子类型和继承的概念是一样的吗?

基于本答案末尾的注释,看起来子类型和继承是Java中略有不同的概念.它是什么?仅当类声明包含extends ...子句时才继承吗?如果是这种情况,那么一个类不会从Object继承,即使它是它的子类型,对吧?

java inheritance subtyping

5
推荐指数
2
解决办法
303
查看次数

Git merge:是否可以避免非快进文件的自动合并?

当我执行 a 操作时git merge,我希望仅自动合并可以快进的文件(即自上次公共修订以来仅在合并的一个分支上更改的文件),而所有其他文件(已更改)在两个分支上,即使在不同的行上)都被标记为冲突。我环顾四周,但似乎没有一种“简单”的方法(例如传递给 的选项git merge)来做到这一点。这里有一个类似的问题,但不完全是这个问题。这里有一个非常相似的问题,但已经有 4 年历史了,而且没有确凿的答案。

git merge

5
推荐指数
1
解决办法
3138
查看次数

tuple() 是否复制参数的元素?

在python中,内置函数是tuple([iterable])创建一个元组对象并用“iterable”元素的副本填充它,还是创建一个包含对“iterable”已经存在的对象的引用的元组?

python tuples

4
推荐指数
1
解决办法
2270
查看次数

C++向量没有任何理由调整大小

我有这段代码:

#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)

c++ stl vector

4
推荐指数
1
解决办法
144
查看次数

std::transform 需要特别注意集合

我不明白为什么这段代码会编译:

#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 …

c++ stl stl-algorithm

3
推荐指数
1
解决办法
6589
查看次数