Переменные объекта не видны из одного потока в другой в Android - PullRequest
0 голосов
/ 01 мая 2018

У меня два потока, обращающихся к одному и тому же объекту RestResource, поток t1 вызывает метод RestResource.GetResource (), а поток t2 вызывает переменную Msg. Поток t2 не может видеть данные переменной Msg, когда они изменяются или обновляются. Посоветуйте пожалуйста как это исправить. Обратите внимание, что поток t2 начинает поток t1 и ожидает его завершения

    public class RestResource()
{
    public volatile String Msg;

    public void GetResource(){
        List<Resource> remoteResourceList = GetRemoteResource(); // Getting List from Remote Server
        for (Resource resource: remoteResourceList){
            switch (resource.resourceType) {
            case 0:
                AA(); break;

            case 1:
                BB(); break;

            case 2:
                CC(); break;

            case 3:
                DD();break;
            }
        }
    }

    private void AA(){
        Msg = "AA is executing";
    }

    private void BB(){
        Msg = "BB is executing";
    }

    private void CC(){
        Msg = "CC is executing";
    }

    private void DD(){
        Msg = "DD is executing";
    }

}

private volatile RestResource restResource = new RestResource(context);
protected void onCreate(Bundle savedInstanceState) {

    Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    _restResource.GetResource();
                }
            });

    Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                   t1.start();
                   while(progress<101){
                   UpdateUI(_restResource.Msg);
                   progress++;
                  }
                }
               t1.join();
            });
}

1 Ответ

0 голосов
/ 01 мая 2018

Поток t2 не может видеть данные переменной Msg при их изменении или обновлении.

На самом деле поле Msg является изменчивым. Таким образом, любое изменение этой переменной будет видно для любого потока, который обращается к ней.
Ваша проблема в том, что поток t2 не видит обновления Msg, потому что его метод run() не заботится об обновлении Msg. Используется только для передачи на UpdateUI():

 UpdateUI(_restResource.Msg);

Тогда поток t2 закончен.
Чтобы иметь возможность использовать новое значение Msg в t2, вы должны разрешить t2 не завершиться и получать уведомления при изменении значения Msg.
Таким образом, он может вызвать UpdateUI(_restResource.Msg); с новым значением.

Обратите внимание, что это будет работать, но добавит дополнительную логику.
На самом деле, кажется, нет необходимости иметь поток для вызова UpdateUI().
Кажется гораздо более естественным, что GetResource() напрямую вызывает метод UpdateUI().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...