Cha*_*ara 47 java jvm system-properties
在Java中,我们使用System.setProperty()方法来设置一些系统属性.根据这篇文章,使用系统属性有点棘手.
System.setProperty()可能是一个邪恶的调用.
- 这是100%线程敌对
- 它包含超全局变量
- 当这些变量在运行时神秘地改变时,调试极其困难.
我的问题如下.
系统属性的范围如何?它们是否特定于每个虚拟机,或者它们具有"超级全局特性",它在每个虚拟机实例上共享相同的属性集?我猜选项1
是否有任何工具可用于监视运行时更改以检测系统属性中的更改.(仅为了便于检测问题)
coo*_*ird 43
系统属性的范围
至少从阅读该System.setProperties
方法的API规范,我无法得到系统属性是否由JVM的所有实例共享的答案.
为了找到答案,我编写了两个快速程序,它们将System.setProperty
使用相同的键设置系统属性,但使用不同的值:
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) {}
}
}
}
Run Code Online (Sandbox Code Playgroud)
(请注意,运行上面的两个程序会使它们进入无限循环!)
事实证明,当使用两个单独的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();
// 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()));
}
}
Run Code Online (Sandbox Code Playgroud)
属性是不是线程安全的?
Hashtable
是线程安全的,所以我也期待这样Properties
做,事实上,Properties
该类的API规范证实了这一点:
此类是线程安全的:多个线程可以共享单个
Properties
对象,而无需外部同步.序列化表单
Max*_*asy 10
系统属性是按进程的.这意味着它们比静态字段更全局,静态字段是每个类加载器.因此,例如,如果您有一个运行多个Java Web应用程序的Tomcat实例,每个实例都有一个com.example.Example
名为静态字段的类globalField
,则webapps将共享系统属性,但com.example.Example.globalField
可以在每个Web应用程序中设置为不同的值.
归档时间: |
|
查看次数: |
32952 次 |
最近记录: |