Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单个线程如何在退出两次之前两次进入同步块?_Java_Android_Concurrency_Synchronization - Fatal编程技术网

Java 单个线程如何在退出两次之前两次进入同步块?

Java 单个线程如何在退出两次之前两次进入同步块?,java,android,concurrency,synchronization,Java,Android,Concurrency,Synchronization,单个线程如何在退出两次之前两次进入同步块 在我的应用程序中,我正在实现一个单例模式,我注意到日志显示一个线程进入同步块两次,然后退出两次。因此,不愉快地创建了两个实例。这怎么可能?我对Java特别感兴趣 public class Singleton { private static volatile Singleton mSingleton; private static final Object mInstanceLock = new Object(); private

单个线程如何在退出两次之前两次进入同步块

在我的应用程序中,我正在实现一个单例模式,我注意到日志显示一个线程进入同步块两次,然后退出两次。因此,不愉快地创建了两个实例。这怎么可能?我对Java特别感兴趣

public class Singleton {
    private static volatile Singleton mSingleton;
    private static final Object mInstanceLock = new Object();
    private Singleton() {
        // Basic initialization.
    }
    public static Singleton getInstance() {
        if (mSingleton == null) {
            log("before synchronized");
            synchronized (mInstanceLock) {
                log("in synchronized start");
                if (mSingleton == null) {
                    mSingleton = new Singleton();
                    log("in synchronized, new Singleton(), " + mSingleton.toString() +
                            " in thread " + Thread.currentThread().getName() +
                            "-" Thread.currentThread().getId());
                }
                log("in synchronized end");
            }
            log("after synchronized");
        }
        return mSingleton;
    }
}
输出,注意创建的不同对象,构造函数在我程序中的每个日志中运行两次,实际上输出当前线程id,但我在上面的代码中忽略了这一点,以便看起来更整洁:

before synchronized, in thread id 1
in synchronized start, in thread id 1
before synchronized, in thread id 1
in synchronized start, in thread id 1
// Basic initialization.
in synchronized, new Singleton(), com.example.app.Singleton@42453090 in thread: main-1
in synchronized end, in thread id 1
after synchronized, in thread id 1
// Basic initialization.
in synchronized, new Singleton(), com.example.app.Singleton@424500b0 in thread: main-1
in synchronized end, in thread id 1
after synchronized, in thread id 1
关于我的问题,这似乎绝对不可能。因此,如果没有一个确切的答案,那么解释是什么导致日志显示相同的线程创建了两个不同的单例也是很好的

额外注意事项,以防万一:

此代码在Android应用程序中运行。 代码大部分是单线程的,但是不同的线程使用单线程。 每次运行代码时都可以重复此操作。 所有同步前和同步中启动的时间戳相同。 同步结束时和同步后对的时间戳关闭约10毫秒。 这不是愚人节的玩笑,哈哈。 我不确定我能提供什么其他信息,请让我知道。。。 评论中的更多信息:

日志只是输出到控制台。更具体地说,它在android中调用android.util.Log.d,这是控制台最基本的调试消息。 它只是一个Java对象,没有其他继承。
什么是日志?在哪里申报?它做什么?我们需要看到整个类,特别是构造函数和静态toString。最有可能的是,您在某个地方有一个递归调用。logString只调用Android中的Log.d,它只输出到控制台,而不应用任何其他应用程序。toString只是Object.toString的java实现,它告诉我对象是不相等的。我将进一步检查代码,看看是否还有其他信息可以添加。哦,静态toString实际上只是一个输入错误。我会更新的。谢谢你,最后。。。如果可能的话,只需为类似的内容使用单个成员枚举。