synchronized关键字在运行时导致了空指针错误?
我写了一个很简单的Singleton,用synchronized关键字来做inst实例引用的访问保护:public class Revert {
public static void main(String[] args) {
Revert.Singleton.GetInstance();
}
static class Singleton{
private static Singleton inst=null;
public static Singleton GetInstance(){
if(inst==null){
synchronized(inst){//JVM memory barrier
inst=new Singleton();
}
}
return inst;
}
Singleton(){System.out.println("ctor");}
}
}
问题是,我一致性就报空指针错误。如果我调试的话,发现调试器会在synchronized那句话那里停留两次,但是根本就不执行inst=new Singleton();这句话。
我的代码有什么问题? 还是我理解的就不对?
我用Eclipse+jdk1.6 本帖最后由 isaacxu 于 2012-08-07 03:36 编辑
也许是讲的不清楚,还是烦请阅读《Effective Java》2nd里,“Item 3: Enforce the singleton property with a private constructor or an enum type”的相关内容,原文:“As of release 1.5, there is a third approach to implementing singletons. Simply make an enum type with one element:”
Joshua Bloch给出的代码:// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}写了一个Enum Singleton的Junit测试用例,在Eclipse里选择File->New->Junit Test Case,可以生成相应的Junit测试文件,然后,Run as Junit Test 就可以了。/**
* File:EnumSingleton.java
* ---------------------------
* for test Enum Singleton
*/
package org.cudemo;
/**
* @author isaacxu
*
*/
public enum EnumSingleton {
INSTANCE;
private String name;
// Private constructor can prevents instant from other classes
private EnumSingleton() {
}
//set a obj name
public void setName(String name) {
this.name = name;
}
//get a obj name
public String getName() {
return name;
}
}
Junit 测试用例/**
* File:EnumSingletonTest.java
* ------------------------------
* This a junit test case for test EnumSingleton
*/
package org.cudemo;
import static org.junit.Assert.*;
import org.junit.Test;
public class EnumSingletonTest {
@Test
public void test() {
EnumSingleton firstObj = EnumSingleton.INSTANCE;
firstObj.setName("Enum");
EnumSingleton secondObj = EnumSingleton.INSTANCE;
secondObj.setName("Singleton");
assertTrue(firstObj == secondObj);
assertEquals("Singleton", firstObj.getName());
assertEquals("Singleton", secondObj.getName());
}
}
/**
* File:MyRevert.java
* ----------------------
* Please read Item 3 in the 2nd Edition of <Effective Java>,Bloch explains three ways of implementing
* a singleton in Java, the best is “Enum as Singleton”.Joshua Bloch is aka Josh Bloch,you can see his
* write code in OpenJdk source code.(e.g.Collections.java)
*/
package org.cudemo;
/**
* @author isaacxu
*
*/
public class MyRevert {
/**
* @param args
*/
public static void main(String[] args) {
MyRevert.Singleton.getInstance();
MyRevert.MyNewSingleton.gotIt();
}
/**
* before Java1.5
* @author isaacxu
*
*/
public static class Singleton {
private static Singleton uniqInstance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (uniqInstance == null) {
uniqInstance = new Singleton();
}
System.out.println("Hi,I am old java Singleton");
return uniqInstance;
}
}
/**
* after Java1.6
*/
public static enum MyNewSingleton {
INSTANCE;
public static void gotIt(){
System.out.println("Hi,I am the best Singleton!");
}
}
}
isaacxu 发表于 2012-08-06 17:58 static/image/common/back.gif
你是说,java1.6以后声明一个INSTANCE就相当于声明了一个Singleton类型? 这么神奇? 我百度了半天Java 1.6 INSTANCE没找到什么有用的信息啊。
页:
[1]