Goetz的"Java Concurrency in Practice"第3.2.1节包含以下规则:
this在施工期间不要让参考物逃逸
我的理解是,在一般情况下,允许this以逃避可能导致其他线程看到您的对象不完全构建版本和违反的初始化安全保障final领域(如讨论如这里)
但是有可能安全泄漏this吗?特别是,如果你happen-before在泄漏之前建立关系?
例如,官方执行官Javadoc说
在将
Runnable对象提交到一个Executor发生之前的一个线程中的操作- 在它执行开始之前,可能在另一个线程中
我对Java内存模型的天真阅读理解是,类似下面的内容应该是安全的,即使它this在构造函数结束之前泄漏:
public final class Foo {
private final String str1;
private String str2;
public Foo(Executor ex) {
str1 = "I'm final";
str2 = "I'm not";
ex.execute(new Runnable() {
// Oops: Leakage!
public void run() { System.out.println(str1 + str2);}
});
}
}
Run Code Online (Sandbox Code Playgroud)
也就是说,即使我们已经泄漏this到潜在的恶意Executor,泄漏 …
我想更好地了解编译器何时隐式实例化成员函数模板.
请考虑以下示例:
// example.h
struct Parent {
virtual void foo(double) {}
};
struct Child : Parent {
void foo(double d) { bar(d); }
template<typename T> void bar(T);
virtual void baz();
};
// example.cpp
#include "example.h"
template <typename T>
void Child::bar(T) {}
void Child::baz() {}
Run Code Online (Sandbox Code Playgroud)
通过编译[g++|clang++] -c example.cpp,GCC和clang都隐式实例化了函数模板Child::bar<double>.但是,以下看似微小的变化阻止了这一点:
foo不虚拟Child不继承Parentbazbaz不虚拟baz使用标题中的声明进行定义是否有关于何时进行隐式实例化的合理简洁解释,还是需要涉及标准的副本?我搜索了SO以寻找与隐式实例化有关的其他问题,但没有找到太多.我找到的最接近的是这个问题,但它是关于类模板中的虚函数(不是成员函数模板).
要明确:我理解通过在头文件中包含定义或显式实例化我需要的模板可以避免此问题.在挖掘为什么一个类(我无意中省略了它的明确实例)仍然愉快地编译和链接时,这仅仅是出于好奇点.