如何正确使用等待和通知方法?

Posted

技术标签:

【中文标题】如何正确使用等待和通知方法?【英文标题】:How to use the wait and notify methods correctly? 【发布时间】:2018-02-04 16:03:52 【问题描述】:

异步调用有问题。 我需要我的“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();
    

【问题讨论】:

你到底在问什么?唯一可辨别的问题的字面答案是“很多人都这样做”。如果您需要帮助,您需要提出一个明确而明确的问题。不是“请帮帮我”或“请给我解释一下”……这两个问题都不是我们可以回答的。 如果您不能提出明确/明确的问题,我最好的建议是寻找更多示例、教程、书籍……并阅读/重读它们,直到您理解为止。或者,找一位准备好就该主题为您提供一对一辅导的专家。提示:*** 不是找到这样一个人的地方。试试你当地的大学... Soo 为什么要写等待方法? 很抱歉这个问题做得不好,我现在已经试过了。我用英文写作有困难,我想对我有一点耐心。 我编辑了你的问题的标题,因为“谁”“哪个人”,我想你想说“如何......”“应该怎么做...”。 【参考方案1】:

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

所以我必须创建改造的同步方法,然后使用线程,这样我就可以使用等待和通知方法而不会冻结应用程序。

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;
        

【讨论】:

区别是什么?错误一直在?治愈的存在?仅仅代码不是答案。你必须解释。 我编辑了帖子以获得解释。不明白的请在下方留言

以上是关于如何正确使用等待和通知方法?的主要内容,如果未能解决你的问题,请参考以下文章

4.等待和通知

如何在没有 IllegalMonitorStateException 的情况下在 Java 中使用等待和通知?

等待QThread时UI会阻塞/如何正确使用QThread

conditon 实现等待/通知

如何使用 rxjava/retrofit 正确等待/观察来自服务器的传入数据

带有等待/通知和没有它们的同步块之间的区别?