我需要(目前)使用一些只能通过jvm属性“配置”的java。
我知道这会影响多线程,因为一个线程修改属性可能会影响其他线程的运行。
所以我想在一个同步的方法中做这件事。
public static sychronized void someMethod(){
Security.setProperty("responderURL",IP);
//do code here
}看起来没问题,但我想知道这上面是否有任何陷阱,以及是否有任何类型的设计模式来处理这些情况?
谢谢
发布于 2011-05-15 17:20:20
当您创建一个同步的静态方法时,它在该方法所在的类上进行同步。这意味着该类中一次只能运行一个方法。如果这解决了你的问题,那就太好了。
但是,如果JVM中的任何其他方法在该类外部或在类上同步的方法外部修改这些属性,那么您所做的工作将不会有任何效果。
发布于 2011-05-15 17:19:09
你不需要同步,System.setProperty已经是同步的方法了,虽然System.getProperty没有同步,但是属性类扩展了HashTable,它有同步的方法来访问它的键值pairs.As结果,你不需要担心同步的问题..
编辑:
关于我的回答的一些澄清;
1.如果你的方法应该作为一个原子单元工作,那么它应该是同步的,比如;
public static sychronized void someMethod(){
if (System.getProperty("responderURL")==null)
System.setProperty("responderURL",IP);
//do code here
//some code
URL url = new URL(System.getProperty("responderURL"),8080,"test.txt");
}您应该同步您的方法,因为当线程1检查responderURL属性时,线程2可以设置此属性。
2.但是,如果您的方法只设置responderURL属性,并且其功能不依赖于respondrURL属性的当前值,则不需要同步您的方法。
public static void someMethod(){
System.setProperty("responderURL",IP);
//do code here
//some code
URL url = new URL(IP,8080,"test.txt");
}发布于 2011-05-16 02:10:13
在这里,使用synchronized不会对您有所帮助。在您的示例中,synchronized做的唯一一件事就是确保两个线程不能同时调用您的同步方法。
public class Foo {
public static synchronized void bar() {
//...
}
}完全相同于
public class Foo {
public static void bar() {
synchronized (Foo.class) {
//...
}
}
}也就是说,只有可以看到Foo.class并在其上进行同步的代码才会受到同步的影响。由于您调用的任何库中的代码显然不知道Foo.class,因此在它上进行同步将不会有任何效果。
如果您想要保证这些系统属性在任何可能读取这些值的代码运行之前设置好,最有效的方法就是将它们作为-D参数传递给启动JVM的java命令,例如java -DresponderURL=http://foo.bar。
下一个最好的方法是,像您正在做的那样,在VM启动的早期用一些方法设置属性。不过,如果可能的话,最好使用命令行参数来实现,原因是:如果在您正在使用的库中的静态{}块中读取任何这样的属性,那么这些块可能会在您的代码运行之前运行,因为Java字节码验证器可能会导致那些类在您的代码执行任何调用它们的操作之前被初始化(您可以通过将-Xverify:none传递给Java命令来避免这种情况,但是如果您可以这样做,那么您也可以在那里设置系统属性)。
https://stackoverflow.com/questions/6007501
复制相似问题