系统属性的作用域
至少从阅读System.setProperties
方法的API规范来看,我无法确定系统属性是否由JVM所有实例共享。
为了找到答案,我编写了两个快速程序,使用相同的键但不同的值通过System.setProperty
设置系统属性:
class T1 {
public static void main(String[] s) {
System.setProperty("dummy.property", "42");
while (true) {
System.out.println(System.getProperty("dummy.property"));
try {
Thread.sleep(500);
} catch (Exception e) {}
}
}
}
class T2 {
public static void main(String[] s) {
System.setProperty("dummy.property", "52");
while (true) {
System.out.println(System.getProperty("dummy.property"));
try {
Thread.sleep(500);
} catch (Exception e) {}
}
}
}
注意运行上述两个程序会导致它们进入无限循环!
事实证明,当使用两个独立的java
进程运行这两个程序时,一个JVM进程中设置的属性值不会影响另一个JVM进程的属性值。
需要说明的是,这是在使用Sun的JRE 1.6.0_12时得出的结果。此行为至少在API规范中未定义(或者我没能找到),其行为可能会有所不同。
是否有工具可以监控运行时更改?
据我所知,并没有此类工具。但是,如果确实需要检查系统属性是否已更改,可以在某个时间点保留Properties
的副本,并将其与对System.getProperties
的另一个调用进行比较--毕竟,Properties
是Hashtable
的子类,因此比较方式类似。
以下是一个演示如何检查系统属性是否更改的程序。这可能不是一种优雅的方法,但它似乎可以完成工作:
import java.util.*;
class CheckChanges {
private static boolean isDifferent(Properties p1, Properties p2) {
Set<Map.Entry<Object, Object>> p1EntrySet = p1.entrySet();
Set<Map.Entry<Object, Object>> p2EntrySet = p2.entrySet();
for (Map.Entry<Object, Object> e : p1EntrySet) {
if (!p2EntrySet.contains(e))
return true;
}
for (Map.Entry<Object, Object> e : p2EntrySet) {
if (!p1EntrySet.contains(e))
return true;
}
return false;
}
public static void main(String[] s)
{
Properties p = (Properties)System.getProperties().clone();
System.setProperty("dummy.property", "42");
System.out.println(isDifferent(p, System.getProperties()));
}
}
Properties类不是线程安全的吗?
我原本以为Hashtable
是线程安全的,因此我也期望 Properties
是线程安全的,而且事实上,Properties
类的API规范也确认了这一点:
这个类是线程安全的: 多个线程可以共享一个单独的Properties
对象, 而无需外部同步。, Serialized Form