在Android中,对象变量在一个线程中不可见

时间:2018-05-01 14:26:04

标签: java android multithreading thread-safety

我有两个线程访问同一个对象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 :(得分:0)

  

t2线程无法在更改或更新时看到Msg变量数据。

实际上Msg字段是不稳定的。因此,对于访问它的任何线程,此变量的任何更改都是可见的 您的问题是t2线程没有看到Msg的更新,因为其run()方法不关心Msg更新。 它只用它将它传递给UpdateUI()

 UpdateUI(_restResource.Msg);

然后t2线程结束 为了能够在Msg中使用t2的新值,您应该允许t2无法完成,并在Msg值更改时收到通知。
通过这种方式,它可以使用新值调用UpdateUI(_restResource.Msg);

请注意,这会有效但会增加额外的逻辑 事实上似乎没有必要让一个线程来调用UpdateUI() GetResource()直接调用UpdateUI()方法似乎更自然。