如何正确使用wait和notify方法?

时间:2017-08-27 02:10:38

标签: java android asynchronous async-await threadpool

我遇到异步调用问题。 我需要我的“do”循环来等待异步调用继续。 但是当你运行方法“lock.wait()”时,应用程序被冻结,异步调用不是cales。

lock.wait();

应用程序已冻结,但未调用下面的命令行,并且应用程序未继续执行以下方法:

callUser.enqueue(new Callback<BaseResponse<User>>() {
    @Override
    public void onResponse(Response<BaseResponse<User>> response, Retrofit retrofit) {
        updateUsersFromServer(response.body());
    }

    @Override
    public void onFailure(Throwable t) {
        UserEvent UserEvent = new UserEvent(
                null, 500, R.string.order_unavailable);
        EventBus.getDefault().post(UserEvent);
    }
});

我需要更好地理解“wait()”方法是什么样的。

如何使应用程序不在“wait()”方法中停止?

public void fetchUser(Integer cdCode, String pinckingListNumber) {
    List<User> Users = new ArrayList<>();
    do {
        fetchUserApi(cdCode, pinckingListNumber);
        synchronized (lock) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                callUser = false;
                UserEvent UserEvent = new UserEvent(
                        null, 500, R.string.order_unavailable);
                EventBus.getDefault().post(UserEvent);
            }
        }
        offset = offset + 10;
        if (!ObjectValidation.isEmptyOrNull(response)) {
            for (int i = 0; i < response.getRecords().size(); i++) {
                Users.add(response.getRecords().get(i));
            }
            if (response.getMeta().getRecordCount() < response.getMeta().getOffset())
                callUser = false;
        } else {
            callUser = false;
            UserEvent UserEvent = new UserEvent(
                    null, 500, R.string.order_unavailable);
            EventBus.getDefault().post(UserEvent);
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            callUser = false;
            UserEvent UserEvent = new UserEvent(
                    null, 500, R.string.order_unavailable);
            EventBus.getDefault().post(UserEvent);
        }
    } while (callUser);

    UserEvent UserEvent = new UserEvent(
            Users, 200, R.string.delivery_success);
    EventBus.getDefault().post(UserEvent);
}

private void fetchUserApi(Integer cdCode, String pinckingListNumber) {
    UserResource UserResource = getRetrofit().create(UserResource.class);
    Call<BaseResponse<User>> callUser = UserResource.getListUsers(
            authController.getTokenHeader(),
            pinckingListNumber,
            cdCode,
            limit,
            offset
    );

    callUser.enqueue(new Callback<BaseResponse<User>>() {
        @Override
        public void onResponse(Response<BaseResponse<User>> response, Retrofit retrofit) {
            updateUsersFromServer(response.body());
        }

        @Override
        public void onFailure(Throwable t) {
            UserEvent UserEvent = new UserEvent(
                    null, 500, R.string.order_unavailable);
            EventBus.getDefault().post(UserEvent);
        }
    });
}

private void updateUsersFromServer(BaseResponse<User> baseResponseUsers) {
    synchronized (lock) {
        response = baseResponseUsers;
        lock.notify();
    }
}

1 个答案:

答案 0 :(得分:-1)

在应用程序的情况下,我不能使用Retrofit异步方法。 我不知道是一些改进的bug,但是当我使用改进的异步方法并执行Wait()命令时,应用程序冻结了。

所以我必须创建改造的同步方法然后使用一个Thread,这样我就可以使用wait和notify方法而不会冻结应用程序。

public void fetchUser(Integer cdCode, String pinckingListNumber) {
     List<User> Users = new ArrayList<>();
        do {
            fetchUserApi(cdCode, pinckingListNumber);
            // My code modification
            synchronized (thread) {
                try {
                    thread.wait();
                } catch (InterruptedException e) {
                    callUser = false;
                    UserEvent UserEvent = new UserEvent(
                            null, 500, R.string.order_unavailable);
                    EventBus.getDefault().post(UserEvent);
                }
            }
            offset = offset + 10;
            if (!ObjectValidation.isEmptyOrNull(response)) {
                for (int i = 0; i < response.getRecords().size(); i++) {
                    Users.add(response.getRecords().get(i));
                }
                if (response.getMeta().getRecordCount() < response.getMeta().getOffset())
                    callUser = false;
            } else {
                callUser = false;
                UserEvent UserEvent = new UserEvent(
                        null, 500, R.string.order_unavailable);
                EventBus.getDefault().post(UserEvent);
            }
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                callUser = false;
                UserEvent UserEvent = new UserEvent(
                        null, 500, R.string.order_unavailable);
                EventBus.getDefault().post(UserEvent);
            }
        } while (callUser);

        UserEvent UserEvent = new UserEvent(
                Users, 200, R.string.delivery_success);
        EventBus.getDefault().post(UserEvent);
    }

    private void fetchUserApi(Integer cdCode, String pinckingListNumber) {
        UserResource userResource = getRetrofit().create(UserResource.class);
        final Call<BaseResponse<User>> callUserAPI = userResource.getListUsers(
                    authController.getTokenHeader(),
                    pinckingListNumber,
                    cdCode,
                    limit,
                    offset
            );
            // My code modification
            thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        updateUsersFromServer(callUserAPI.execute().body());
                        synchronized (thread) {
                            thread.notify();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });

            thread.start();
    }
    private void updateUsersFromServer(BaseResponse<User> baseResponseUsers) {
            response = baseResponseUsers;
        }