Java 系统属性的范围
在 Java 中,我们使用 System.setProperty() 方法来设置一些系统属性.根据这篇文章,系统属性的使用有点棘手.
In Java we use System.setProperty() method to set some system properties. According to this article the use of system properties is bit tricky.
System.setProperty() 可能是一个邪恶的调用.
System.setProperty() can be an evil call.
- 它是 100% 线程敌对的
- 它包含超全局变量
- 当这些变量神秘莫测时,调试起来非常困难在运行时更改.
我的问题如下.
系统属性的范围如何?它们是特定于每个虚拟机的,还是具有超级全局性质",在每个虚拟机实例上共享相同的属性集?我猜选项 1
How about the scope of the system properties? Are they specific for each and every Virtual Machine or they have a "Super Global nature" that shares the same set of properties over Each and every virtual machine instance? I guess the option 1
是否有任何工具可用于监控运行时更改以检测系统属性的更改.(只是为了方便问题检测)
Are there any tools that can be used to monitor the runtime changes for detect the changes in System properties. (Just for the ease of problem detection)
推荐答案
系统属性范围
至少从阅读 System.setProperties
方法,我无法回答系统属性是否由 JVM 的所有实例共享.
At least from reading the API Specifications for the System.setProperties
method, I was unable to get an answer whether the system properties are shared by all instances of the JVM or not.
为了找出答案,我编写了两个快速程序,它们将通过 System.setProperty
设置系统属性,使用相同的键,但值不同:
In order to find out, I wrote two quick programs that will set the system property via System.setProperty
, using the same key, but different values:
class T1 {
public static void main(String[] s) {
System.setProperty("dummy.property", "42");
// Keep printing value of "dummy.property" forever.
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");
// Keep printing value of "dummy.property" forever.
while (true) {
System.out.println(System.getProperty("dummy.property"));
try {
Thread.sleep(500);
} catch (Exception e) {}
}
}
}
(请注意,运行上面的两个程序会使它们陷入无限循环!)
(Beware that running the two programs above will make them go into an infinite loop!)
事实证明,当使用两个独立的java
进程运行这两个程序时,一个JVM进程中设置的属性值不会影响另一个JVM进程的值.
It turns out, when running the two programs using two separate java
processes, the value for the property set in one JVM process does not affect the value of the other JVM process.
我应该补充一点,这是使用 Sun 的 JRE 1.6.0_12 的结果,并且这种行为至少在 API 规范中没有定义(或者我找不到它),行为可能会有所不同.
I should add that this is the results for using Sun's JRE 1.6.0_12, and this behavior isn't defined at least in the API specifications (or I haven't been able to find it), the behaviors may vary.
是否有任何工具可以监控运行时变化
据我所知.但是,如果确实需要检查系统属性是否发生变化,可以一次保留 Properties
的副本,并将其与对 System.getProperties 的另一次调用进行比较
-- 毕竟,Properties
是 Hashtable
,所以会以类似的方式进行比较.
Not to my knowledge. However, if one does need to check if there were changes to the system properties, one can hold onto a copy of the Properties
at one time, and compare it with another call to System.getProperties
-- after all, Properties
is a subclass of Hashtable
, so comparison would be performed in a similar manner.
下面的程序演示了一种检查系统属性是否发生变化的方法.可能不是一个优雅的方法,但它似乎完成了它的工作:
Following is a program that demonstrates a way to check if there has been changes to the system properties. Probably not an elegant method, but it seems to do its job:
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();
// Check that the key/value pairs are the same in the entry sets
// obtained from the two Properties.
// If there is an difference, return true.
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)
{
// System properties prior to modification.
Properties p = (Properties)System.getProperties().clone();
// Modification of system properties.
System.setProperty("dummy.property", "42");
// See if there was modification. The output is "false"
System.out.println(isDifferent(p, System.getProperties()));
}
}
属性不是线程安全的?
哈希表
是线程安全的,所以我期待 Properties
也是如此,事实上,Properties
类确认:
Hashtable
is thread-safe, so I was expecting that Properties
would be as well, and in fact, the API Specifications for the Properties
class confirms it:
这个类是线程安全的:多个线程可以共享一个 Properties
对象无需外部同步,序列化表单
This class is thread-safe: multiple threads can share a single
Properties
object without the need for external synchronization., Serialized Form
相关文章