免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5149 | 回复: 3

synchronized关键字在运行时导致了空指针错误? [复制链接]

论坛徽章:
0
发表于 2012-08-06 15:15 |显示全部楼层
10可用积分
我写了一个很简单的Singleton,用synchronized关键字来做inst实例引用的访问保护:

  1. public class Revert {
  2.         public static void main(String[] args) {
  3.                 Revert.Singleton.GetInstance();
  4.         }
  5.         static class Singleton{
  6.                 private static Singleton inst=null;
  7.                 public static Singleton GetInstance(){
  8.                         if(inst==null){
  9.                                 synchronized(inst){//JVM memory barrier
  10.                                         inst=new Singleton();
  11.                                 }
  12.                         }
  13.                         return inst;
  14.                 }
  15.                 Singleton(){System.out.println("ctor");}
  16.         }
  17. }
复制代码
问题是,我一致性就报空指针错误。如果我调试的话,发现调试器会在synchronized那句话那里停留两次,但是根本就不执行inst=new Singleton();这句话。

我的代码有什么问题? 还是我理解的就不对?
我用Eclipse+jdk1.6

最佳答案

查看完整内容

也许是讲的不清楚,还是烦请阅读《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的Junit测试用例,在Eclipse里选择File->New->Junit Test Case,可以生成相应的Juni ...

论坛徽章:
0
发表于 2012-08-06 15:15 |显示全部楼层
本帖最后由 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给出的代码:
  1. // Enum singleton - the preferred approach
  2. public enum Elvis {
  3. INSTANCE;
  4. public void leaveTheBuilding() { ... }
  5. }
复制代码
写了一个Enum Singleton的Junit测试用例,在Eclipse里选择File->New->Junit Test Case,可以生成相应的Junit测试文件,然后,Run as Junit Test 就可以了。
  1. /**
  2. * File:EnumSingleton.java
  3. * ---------------------------
  4. * for test Enum Singleton
  5. */
  6. package org.cudemo;

  7. /**
  8. * @author isaacxu
  9. *
  10. */
  11. public enum EnumSingleton {

  12.         INSTANCE;
  13.        
  14.         private String name;

  15.         // Private constructor can prevents instant from other classes
  16.         private EnumSingleton() {
  17.         }
  18.     //set a obj name
  19.         public void setName(String name) {
  20.                 this.name = name;
  21.         }
  22.     //get a obj name
  23.         public String getName() {
  24.                 return name;
  25.         }

  26. }

复制代码
Junit 测试用例
  1. /**
  2. * File:EnumSingletonTest.java
  3. * ------------------------------
  4. * This a junit test case for test EnumSingleton
  5. */
  6. package org.cudemo;

  7. import static org.junit.Assert.*;

  8. import org.junit.Test;

  9. public class EnumSingletonTest {

  10.         @Test
  11.         public void test() {
  12.                 EnumSingleton firstObj = EnumSingleton.INSTANCE;
  13.             firstObj.setName("Enum");
  14.             EnumSingleton secondObj = EnumSingleton.INSTANCE;
  15.             secondObj.setName("Singleton");
  16.             assertTrue(firstObj == secondObj);
  17.             assertEquals("Singleton", firstObj.getName());
  18.             assertEquals("Singleton", secondObj.getName());
  19.             
  20.         }

  21. }
复制代码

论坛徽章:
0
发表于 2012-08-06 17:58 |显示全部楼层
  1. /**
  2. * File:MyRevert.java
  3. * ----------------------
  4. *         Please read Item 3 in the 2nd Edition of <Effective Java>,  Bloch explains three ways of implementing
  5. * a singleton in Java, the best is “Enum as Singleton”.Joshua Bloch is aka Josh Bloch,you can see his
  6. * write code in OpenJdk source code.(e.g.Collections.java)
  7. */
  8. package org.cudemo;

  9. /**
  10. * @author isaacxu
  11. *
  12. */
  13. public class MyRevert {

  14.         /**
  15.          * @param args
  16.          */
  17.         public static void main(String[] args) {
  18.                
  19.                 MyRevert.Singleton.getInstance();
  20.                 MyRevert.MyNewSingleton.gotIt();

  21.         }
  22.         /**
  23.          * before Java1.5
  24.          * @author isaacxu
  25.          *
  26.          */
  27.         public static class Singleton {
  28.                 private static Singleton uniqInstance;

  29.                 private Singleton() {
  30.                        
  31.                 }

  32.                 public static synchronized Singleton getInstance() {
  33.                         if (uniqInstance == null) {
  34.                                 uniqInstance = new Singleton();
  35.                         }
  36.                         System.out.println("Hi,I am old java Singleton");
  37.                         return uniqInstance;
  38.                 }
  39.                
  40.         }
  41.         /**
  42.          * after Java1.6
  43.          */
  44.         public static enum MyNewSingleton {
  45.                 INSTANCE;
  46.                 public static void gotIt(){
  47.                         System.out.println("Hi,I am the best Singleton!");
  48.                 }
  49.        
  50.         }

  51. }
复制代码

论坛徽章:
0
发表于 2012-08-06 22:45 |显示全部楼层
isaacxu 发表于 2012-08-06 17:58


你是说,java1.6以后声明一个INSTANCE就相当于声明了一个Singleton类型? 这么神奇? 我百度了半天Java 1.6 INSTANCE没找到什么有用的信息啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会

【架构革新 高效可控】2020年12月21日-23日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP