java静态方法问题 大家都知道,java静态方法只初始化一次,我在想一个问题,既然就初始化一次,在进行并行操作的时候会不会有“同步问题”哦,请大家帮我解释下哦 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 大家看下public class Singleton {private Singleton(){} //在自己内部定义自己一个实例,是不是很奇怪? //注意这是private 只供内部调用 private static Singleton instance = new Singleton(); //这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance() { return instance; } } 第二种形式: public class Singleton { private static Singleton instance = null; public static synchronized Singleton getInstance() { //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次 //使用时生成实例,提高了效率! if (instance==null) instance=new Singleton();return instance; } } 我个人认为,第一种的单体模式在多线程下有同步问题,不知道大家怎么看? 第二种有问题,synchronized(Singleton.class){ if(instance == null){ synchronized(Singleton.class){ if(instance == null){ instance = new Singleton (); } } }} 第一种形式没线程问题是因为类成员instance在首次加载时就实例化好了吧,也就是说不是上面红色注释中说明的“每次都进行生成对象”?但是不是很清楚有没可能多个线程同时“首次”加载这种情况,这点望了解的兄弟说明一下。第二种形式有synchronized关键字,就消除了同步问题。7楼说有问题,详细说说你的看法,谢了。 答:我的意思是说:第一种没有问题。不需要加synchronized.而第二种有读/写冲突可能(或可能生成多个对象),因而必需要加synchronized。若已经加了,就正确了。另外,“但是不是很清楚有没可能多个线程同时“首次”加载这种情况,这点望了解的兄弟说明一下。 ”对于这一点,JLS中讲得很清楚:类的初始化过程,是JVM自动保证同步化了。因此:你的“可能多个线程同时“首次”加载这种情况”担心是多余的。 static与synchronized没有联系,这就是说,static的方法一样会出现同步的问题,但同步的问题只是发生在对同一资源有改变操作的情况下,如果这种操作没有任何改变,只是像7楼所说的读操作一样。那么即使加与不加synchronized也没有什么不一样 同步问题的重点在于读写操作,而不在于初始化。所以,即使是static,如果进行了读写操作,同样存在同步的问题。 我觉得同步是在多线程程序中才会有的,且同步的是临界资源。如果不是多线程的程序,那完全没必要考虑同步问题。如果是多线程的程序,就当前第一个类中的声明,虽然是静态方法,但没有用synchronized关键字,同样会有同步问题。参考线程相关书籍就能很快明白咯(*^__^*) java的static方法怎么都扯到synchronized,一般做为static的方法都是些工具类的方法,只要里面没有带属性的static的变量就不会有同步的问题。比如public static insert(String sql){ Dao.executeSql(sql);} 同步和Static没有必然的联系,变量在多线程中都可能存在同步问题,楼主需要好好理解一下同步的概念。 晕:害人不浅啊!啥叫初始化,就是类从磁盘装载之后,jvm自动调用的东西,在初始化完成之前,这个类是不能被应用使用的。当然,jvm也绝对不会把一个类装载并初始化多次。 所以,静态初始化的那部分代码,是永远没有什么同步问题。 楼主可以看看java的24种模式中的单例模式 也许能够解决你的问题 11 楼说的准确。类的初始化是 VM 保证同步的,所以使用第一种方法最简单,特别是这个 instance 并不是占用吓人的内存用量的时候。用空间换时间这时候非常地划算的。 编写一个方法,返回一个double型二维数组 switch出错,换成if却可以,为什么 Java连接数据库的奇怪问题!急!! SOS! SOS! SOS! input窗口一闪而过,不能输入 用response将一个excel文件输出到客户端,如何实现? 关于csv解析的一个问题 新来的,发个自己写的JAVA开窗户游戏 请问,有在诺基亚工作的高手么?诺基亚主要用的是什么技术? 再续问题-----java对象内存地址的问题??????( 求推荐一本靠谱的讲jsp的好书 完全平方数问题
public class Singleton {
private Singleton(){}
//在自己内部定义自己一个实例,是不是很奇怪?
//注意这是private 只供内部调用
private static Singleton instance = new Singleton();
//这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}
第二种形式: public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
//使用时生成实例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance; }
} 我个人认为,第一种的单体模式在多线程下有同步问题,不知道大家怎么看?
synchronized(Singleton.class){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton ();
}
}
}
}
第二种形式有synchronized关键字,就消除了同步问题。7楼说有问题,详细说说你的看法,谢了。
另外,“但是不是很清楚有没可能多个线程同时“首次”加载这种情况,这点望了解的兄弟说明一下。
”
对于这一点,JLS中讲得很清楚:类的初始化过程,是JVM自动保证同步化了。因此:你的“可能多个线程同时“首次”加载这种情况”担心是多余的。
如果不是多线程的程序,那完全没必要考虑同步问题。
如果是多线程的程序,就当前第一个类中的声明,虽然是静态方法,但没有用synchronized关键字,同样会有同步问题。
参考线程相关书籍就能很快明白咯(*^__^*)
一般做为static的方法都是些工具类的方法,只要里面没有带属性的static的变量就不会有同步的问题。
比如
public static insert(String sql){
Dao.executeSql(sql);
}
当然,jvm也绝对不会把一个类装载并初始化多次。
所以,静态初始化的那部分代码,是永远没有什么同步问题。