用领域替换全局变量和同步块

时间:2016-12-05 04:31:46

标签: android concurrency realm synchronized

我改写了这个问题,以免让人们迷惑我正在做的事情。原始问题中使用的示例过于简化了。

我的项目是基于客户端/服务器的。 Android应用程序是客户端。为了恰当地简单地说明这种情况,我们可以想到我有两个意图/活动和一个后台线程。活动A是登录。活动B是应用程序的其余部分。后台线程是一个套接字线程,它需要一直保持,直到用户退出应用程序,或者网络连接中断。

实现状态机来处理应用程序状态,所有活动和套接字线程都需要此状态机。

Singleton很容易满足我的设计要求,但会有很多同步块和等待语句。我想知道是否有可能使用领域来实现相同的目标

原始问题

我是Realm Java(Android)开发的新手。在我当前的代码中,我有一堆全局变量,并在一些AsyncTask或后台线程中使用它们。

我将在这里使用一些代码来说明我的例子

//Class holding global variable
public class GlobalInfo{
    public static String info;
}

//Class changing the global variable
class A{
    void doSomething(){
        String info = GlobalInfo.info;
        info = "start";
        synchronized(info){                
            ...... //do something
            info = "done";
            info.notifyAll();
        }
    }
}

//background thread waiting for info to be "done". Neglecting the class holding it
void doSomethingAfterDone(){
    String info = GlobalInfo.info;
    synchronized(info){                
        while(!info.Equals("done")){
            info.wait();
        }
        //do something
    }
}

假设在调用doSomethingAfterDone()时,方法doSomething()仍在运行。因此,doSomethingAfterDone()将在退出doSomething()循环之前等待while通知。

是否可以使用Realm替换它们?例如,使用领域事务+监听器等待更改,而不是在全局变量上应用synchronized块并等待其通知?

我发现Realm.waitForChange()会阻止执行,直到对其进行了更改。但是,适用于注册或复制到域的任何对象的所有更改是否都会为此语句返回true,无论更改内容是什么?

我知道我可以在意图之间传递字符串,但我想知道领域是否可以完成这项工作。

1 个答案:

答案 0 :(得分:0)

嗯,你通常根本不需要全局变量。您可以在后台线程上写入Realm,并在UI线程上监听更改。

//Class holding global variable
//public class GlobalInfo{
    //public static String info;
//}

//Class changing the global variable
class A{
    void doSomething(){
        //String info = GlobalInfo.info;
        //info = "start";
        //synchronized(info){                
        try(Realm realm = Realm.getDefaultInstance()) {
            realm.executeTransaction(new Realm.Transaction() { // assuming background thread
                @Override
                public void execute(Realm realm) {
                    //!! do something with Realm
                }
            });
        }
        new Thread(new Runnable() { // could be merged to this background thread
            @Override
            public void run() {
               doSomethingAfterDone();
            }
        }).start();
            //info = "done";
            //info.notifyAll();
        //}
    }
}

//background thread waiting for info to be "done". Neglecting the class holding it
void doSomethingAfterDone(){
    //String info = GlobalInfo.info;
    //synchronized(info){                
        //while(!info.Equals("done")){
        //    info.wait();
        //}
        try(Realm realm = Realm.getDefaultInstance()) {
            realm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    //do something
                }
            });
        }
    //}
}