Java 系统属性的范围
在Java中我们使用System.setProperty()方法来设置一些系统属性。 根据这篇文章,系统属性的使用有点棘手。
System.setProperty() 可能是一个邪恶的调用。
- 它是 100% 线程敌对的
- 它包含超全局变量
- 当这些变量神秘莫测时,调试起来非常困难 在运行时更改。
我的问题如下。
系统属性的范围如何? 它们是特定于每个虚拟机的,还是具有“超级全局性”,在每个虚拟机实例上共享相同的属性集? 我猜选项1
是否有任何工具可用于监视运行时更改以检测系统属性的更改。 (只是为了方便问题检测)
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() can be an evil call.
- It is 100% thread-hostile
- It contains super-global variables
- It is extremely difficult to debug when these variables mysteriously
change at runtime.
My questions are as follows.
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
系统属性的范围
至少要阅读
System.setProperties
方法,我无法得到系统属性是否由所有实例共享的答案是否有 JVM。为了找到答案,我编写了两个快速程序,它们将使用相同的键但不同的值通过 System.setProperty 设置系统属性:(
请注意,运行上面的两个程序将使它们进入无限循环!)
事实证明,当使用两个单独的 java 进程运行两个程序时,一个 JVM 进程中设置的属性值不会影响另一个 JVM 进程的值。
我应该补充一点,这是使用 Sun 的 JRE 1.6.0_12 的结果,并且这种行为至少在 API 规范中没有定义(或者我还没有找到它),行为可能会有所不同。
是否有任何工具可以监视运行时更改
据我所知。 但是,如果确实需要检查系统属性是否发生更改,则可以一次保留一份
Properties
副本,并将其与另一次对System.getProperties 的调用进行比较
-- 毕竟,属性
是 < 的子类code>Hashtable,因此将以类似的方式进行比较。以下程序演示了检查系统属性是否已更改的方法。 可能不是一个优雅的方法,但它似乎完成了它的工作:
属性不是线程安全的?
Hashtable
是线程安全的,所以我期望Properties 也是如此,事实上,
Properties
类确认了这一点:Scope of the System properties
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.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:(Beware that running the two programs above will make them go into an infinite loop!)
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.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.
Are there any tools to monitor runtime changes
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 toSystem.getProperties
-- after all,Properties
is a subclass ofHashtable
, 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:
Properties is not thread-safe?
Hashtable
is thread-safe, so I was expecting thatProperties
would be as well, and in fact, the API Specifications for theProperties
class confirms it:系统属性是每个进程的。 这意味着它们比静态字段更具全局性,静态字段是每个类加载器的。 例如,如果您有一个运行多个 Java Web 应用程序的 Tomcat 实例,每个应用程序都有一个带有名为
globalField
的静态字段的类com.example.Example
,那么Web 应用程序将共享系统属性,但可以在每个 Web 应用程序中将 com.example.Example.globalField 设置为不同的值。System properties are per-process. This means that they are more global than static fields, which are per-classloader. So for instance, if you have a single instance of Tomcat running multiple Java webapps, each of which has a class
com.example.Example
with a static field namedglobalField
, then the webapps will share system properties, butcom.example.Example.globalField
can be set to a different value in each webapp.是的,“系统属性”是针对每个虚拟机的(尽管有许多“神奇”属性包含有关主机系统的信息,例如:“os.name”、“os.arch”等)。
至于你的第二个问题:我不知道有这样的工具,但如果你担心系统属性发生变化,你可以使用特殊的 SecurityManager 来防止(甚至可能跟踪)系统属性更改。
Yes, "system properties" are per-VM (though there are a number of "magic" properties that contain information about the host system, eg: "os.name", "os.arch", etc.).
As for your second question: I am not aware of such a tool, but if you're concerned abut system properties getting changed you could use a special SecurityManager to prevent (and perhaps even track) system property changes.
每个虚拟机都有一份属性副本。 它们与其他静态变量(包括单例)有很多相同的问题。
我想,作为一种黑客,您将
System.setProperties
调用到Properties
的一个版本,该版本根据上下文(线程、调用堆栈、一天中的时间等)做出不同的响应。 )。 它还可以使用 System.setProperty 记录任何更改。 您还可以设置SecurityManager
记录相关权限的安全检查。There is one copy of the properties per VM. They have much the same problems as other statics (including singletons).
I guess, as a hack, you call
System.setProperties
to a version ofProperties
that responds differently depending on the context (thread, call stack, time of day, etc.). It could also log any changes withSystem.setProperty
. You could also set aSecurityManager
logs security checks for the relevant permissions.它们的范围是正在运行的 JVM,但除非您有一些深奥的类加载器问题,否则带有属性对象的静态变量将执行相同的操作,并且有机会同步或执行您需要的任何其他操作。
Their scope is the running JVM, but unless you have some esoteric class loader issues a static variable with a properties object will do the same thing, and with the opportunity to syncronize or do whatever else you need.
当您启动一个新的 JVM 时,它会复制环境变量并在其整个生命周期中使用它们。 因此,如果你改变那个环境,他们将仍然受到限制。
我遇到的奇怪行为和我正在调查的奇怪行为略有不同:如果我启动一个 JVM,声明一些影响我在应用程序中使用的库的行为的环境变量(命令行上的 -D 参数)。 但是,如果在 java 代码内部(它们可见)对它们进行更改,则这些更改似乎不会影响库的行为。 奇怪的是我们在同一个JVM中!
When you start a new JVM, it makes a copy of enviroment variables and uses them for all life-cycle of it. So if you makes changes to that enviroment, they would remain confined to it.
The strange behavior I have encountered and on which I am investigating is slightly different: if I start a JVM declaring some of the environment variables (-D argument on cmd line) that affect the behavior of libraries I use in my applications. But if, inside the java code (where they are visible), I make changes to them, it seems that these changes do not affect the behavior of libraries. The strange is that we are in the same JVM!
您没有说明使用系统属性的动机是什么。
我们使用 Spring 进行配置,并使用注入 XML 的属性文件设置初始属性。 应用程序运行时对配置的更改是通过使用 JMX 进行的。
当然,还有许多其他方法可以使用属性文件、基于 xml 的配置等来更改 Java 中的配置。
You don't say what your motivation is for using system properties.
We use Spring for our configuration and set initial properties using a properties file that is injected into the XML. Changes to configuration whilst the app is running are made by using JMX.
There are - of course - many other ways to change configuration in Java using properties file, xml based configuration etc.