在Java中,我们使用System.setProperty()方法来设置一些系统属性。根据本文的介绍,使用系统属性有些棘手。
System.setProperty()可能是一个邪恶的调用。
- 这是100%线程敌对的
- 它包含超全局变量
- 当这些变量在运行时发生神秘变化时,调试非常困难。
我的问题如下。
系统属性的范围如何?它们是针对每个虚拟机专用还是具有“超全局性”,在每个虚拟机实例上共享相同的属性集?我猜选项1
是否有任何工具可用于监视运行时更改以检测系统属性中的更改。(只是为了方便问题检测)
系统属性的范围
至少通过阅读该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) {}
}
}
}
(请注意,运行上面的两个程序会使它们陷入无限循环!)
事实证明,当使用两个单独的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()));
}
}
属性不是线程安全的吗?
Hashtable
是线程安全的
,因此我期望它Properties
也是这样,实际上,Properties
该类的API规范证实了这一点:
这个类是线程安全的:多个线程可以共享一个单一的
Properties
,对象,而不需要外部同步,序列化表格
问题内容: 在詹金斯中是否有任何“适当”的方法来更改系统属性?更改它们的最简单/最快的方法是什么?例如,我需要关闭无用的(在我的情况下)ping线程。 问题答案: 如果您确实想要快速简单的方法来更改系统属性,则可以使用脚本控制台 但这不会在重新启动后幸存下来。要使其永久,请将设置添加到java args。对于我(CentOS,Jenkins 2.7.1)而言,这大约是一半(对于其他发行版,我认为是
当我尝试获取字符串tempdir=System时。getProperty(“java.io.tmpdir”);它将返回我的操作系统“temp”目录路径。e、 普通java应用程序中的g.C:\Users\DATAGU~1\AppData\Local\Temp\。这是正确的。 但是,当我尝试在部署在tomcat6上的web应用程序上获取相同的属性时,它会返回tomcat temp目录路径(例如D:\
Jboss版本:jboss-as-7.1.0.Final 我们能不能加上 在独立满.xml? 我得到以下错误: 在 [行,列]:[479,1] 我有以下条目:
问题内容: JVM中的系统属性System.getProperties()和环境变量System.getenv()有什么区别? 问题答案: 我认为两者之间的区别归结为访问。系统环境变量可以由任何进程访问,而Java系统属性只能由添加到它们的进程访问。 另外,正如Bohemian所说,env变量是在OS中设置的(但是可以通过Java设置),而系统属性则作为命令行选项传递或通过设置setPropert
问题内容: 我们的代码使用了许多系统属性,例如’java.io.tmpdir’,’user.home’,’user.name’等。我们在任何地方都没有为这些常量定义任何常量(我认为Java也没有)或处理它们的任何其他聪明的事情,因此它们在整个代码中都是乱七八糟的。 每个人如何使用系统属性? 问题答案: 我将把它当作您遍历整个代码的任何其他String常量,并为其定义一个常量变量。当然,在这种情况下
所以我使用的是java系统。getProperties(“user.home”)。这是我遇到的问题,我在需要管理员权限的安装过程中调用它,在安装过程中,我需要在用户目录中保存一些文件(例如c:\Users\myname\AppData\Local\SavedFiles)。出现如下步骤所示的问题: 1) 用户mbrando登录windows 8 2)他运行的安装程序 3)系统提示他使用管理员权限登录