Aquarids
Aquarids

Reputation: 85

Android Same instance output different result

I outputted the same object at the same time but I got different results... What could be the cause of DIFFERENT result?

The function in UserHelper.class:

public void login(String phone, String password) {
    UserModel.logInInBackground(phone, password, new LogInCallback<UserModel>() {
        @Override
        public void done(UserModel userModel, AVException e) {
            if (null != userModel) {
                if (userModel.getPosition() == UserModel.USER_BUYER) {
                    refresh();
                    DebugLog.e("fuck" + mUserStatus + UserInstance.getInstance().getUserStatus());
                    for (UserListener listener : listeners)
                        listener.OnUserLogin();
                } else if (userModel.getPosition() == UserModel.USER_SELLER)
                    logout();
            } else for (UserListener listener : listeners)
                listener.HandleError(e.getCode());
        }
    }, UserModel.class);

public USER_STATUS getUserStatus() {
    return mUserStatus;
}

And the UserInstance.class.

public class UserInstance {
    public static UserHelper mInstance;

public static UserHelper getInstance() {
    if (null == mInstance) mInstance = new UserHelper();
    DebugLog.e(mInstance.toString());
    return mInstance;
  }
}

Upvotes: 1

Views: 90

Answers (2)

Aquarids
Aquarids

Reputation: 85

Ultimately, I get the same instance..

Thanks to Shlomi Uziei. I forgot to use double locking pattern. And I should not make mInstance static...

Upvotes: 0

Shlomi Uziel
Shlomi Uziel

Reputation: 908

First of all, if you meant the UserHelper class to be a singleton, why do you access the USER_STATUS instance using UserInstance.getInstance().getUserStatus() instead of just getUserStatus() ?

Second of all, you probably get different instances of UserHelper if the singleton is accessed from different threads, because your implementation is not thread-safe.

A correct implementation would be using a double locking pattern:

public class UserInstance {
    public static UserHelper mInstance;
    private static final ReentrantLock lock = new ReentrantLock();

    public static UserHelper getInstance() {
        if (null == mInstance){
            lock.lock();
            try{
               if (null == mInstance){
                    mInstance = new UserHelper();
               }
            }
            finally{
                lock.unlock();
            }
        }
        DebugLog.e(mInstance.toString());
        return mInstance;
  }

}

Upvotes: 1

Related Questions