实际上我只关注HotSpot 7/8/9,但也很了解其他人。
我是否可以执行以下操作并始终期望打印输出:
public class Main {
static final PrintStream MY_THREAD_LOCAL_PS = new MySpecialPS();
public static void main(String... args) {
System.setOut(MY_THREAD_LOCAL_PS);
System.out.println("/Me written!");
}
}
MySpecialPS只允许从线程写入,从中调用其构造函数(例如,在构造函数中将线程局部布尔值设置为true)。
答案 0 :(得分:2)
通常,您可以确信,在访问任何静态成员,调用其任何静态方法或实例化之前,只需要一个线程初始化一个类。但是,不能确信执行其中一个操作的第一个线程将是初始化类的线程。
应用程序的主类当然有点特别,但据我所知,语言规范或VM规范中没有任何内容保证该类将由后来调用的同一个线程初始化它的main()
方法也是。从这个意义上讲,假设像你提出的Java程序会成功发出任何输出是不安全的。
当然,您可以针对此行为测试现有VM。我假设你发现的那种方式在每个VM实现中都是一致和可靠的。我建议您尽量避免依赖于这些未指定的实现细节,即使在测试之后也是如此。无论你想做什么,找到另一种方式。