Java Singleton不起作用

时间:2014-07-04 14:48:03

标签: java eclipse singleton soot

我通过SOOT-ECLIPSE插件设置一个类作为主类,并希望它像单例一样运行。但是我的实现似乎不起作用,因为每次运行都会得到不同的实例。

我尝试使用包装器并从那里调用单例类,以避免出现这种情况 这个类是由soot的类加载器收集的垃圾。但我也得到了不同的实例。

我确认它在一个JVM上运行,因为我在每次运行时获得的PID相同 到每次运行时更改的类的实例。

我真的很感激对这一点的任何见解。

public class MyMain{

    private static boolean isFirstInstance = true;

    private static class MyMainHolder {
        private static final MyMain INSTANCE = new MyMain();
    }

    public static synchronized MyMain getInstance() {
        return MyMainHolder.INSTANCE;
    }

    private MyMain() {
        if (MyMainHolder.INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }


    public static void main(String[] args) {
    System.out.println("PID: " + ManagementFactory.getRuntimeMXBean().getName());

    MyMain tmp = getInstance();
    }

2 个答案:

答案 0 :(得分:5)

(来自评论......)

  

我的观点是我想运行这个类并且每次都获得相同的实例。

听起来你对单身人士有什么误解。如果你两次运行你的应用程序,即

$ java MyApp
[output]

$ java MyApp
[output]

然后这些是完全独立的JVM调用。第一次运行完成后, 不再有实例 - JVM分配的所有内存都将被释放。

如果你需要一个持久性对象(即即使Java没有运行仍然存在的对象),那么这是一个非常不同的场景,你应该看一下序列化 - 虽然你仍然不应该期望在JVM的不同实例上运行的两个应用程序在内存中看到相同的对象。

编辑:既然我们知道您在Soot下运行,那么每次都可以创建一个单独的类加载器,这样您就可以获得不同的实例那个的方式。从根本上说,您需要了解代码运行的上下文,并在问题中提供该信息(以及您正在观察的内容)。

答案 1 :(得分:1)

看来,OP实际上希望能够在程序的第一次运行和后续运行之间进行区分。这样就可以了:

public static void main(String[] args) {
    File file = new File("has_been_run");
    if (!file.exists()) {
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // first time
    } else {
        // subsequent times
    }
}

显然,文件是以某种方式删除的,然后算作"第一次运行"试。

因此可以使用您可用的任何持久数据存储执行类似操作。