复制服务和同步

时间:2017-10-25 19:03:44

标签: java android synchronized

在Service.java中启动TimeThread.java 当Service.java运行重复时会出现问题。

为什么'isWait'值在'Log.d(“isRun1”)'中为true而在'Log.d(“isRun2”)'中为false?

我想知道'重复运行服务'和'同步'。

我的代码是:

Service.java

thread.pauseNrestart(false);

Thread.java

    public class TimeThread extends Thread {

Handler handler;
boolean isRun = true;
boolean isWait = false;

public TimeThread(Handler handler) {
    this.handler = handler;
}

public void pauseNResume(boolean isWait) {

    synchronized (this) {

        this.isWait = isWait;
            *Log.d("isRun1 :" + isRun + "");*
        notify();
    }
}

public void run() {
    while (isRun) {
         *Log.d("isRun2 :" + isRun + "");*
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            // TODO: handle exception
        }
        if (isWait) {
            try {
                synchronized (this) {
                    wait();
                }
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
        handler.sendEmptyMessage(0);
    }
}

}

1 个答案:

答案 0 :(得分:0)

优化发生时,某些代码行可能会被重新排序:
- 编译时编译器通过重新排序来优化代码;
- JVM可以通过重新排序来动态优化代码;
- 硬件可以通过重新排序来优化性能。

所以代码部分:

#include <memory>

using std::shared_ptr;

class List {
    private:
        const shared_ptr<const List> tail;

        static const List* insertBulk_(unsigned amount, const List*& tail) {
            if (!amount) {
                const List* result = tail;
                tail = nullptr;
                return result;
            }
            return insertBulk_(amount - 1, tail = new List{tail});
        }
        ~List() {}
    public:
        List(const List* tail): tail{tail, List::destroy} {}
        List(const shared_ptr<const List>& tail): tail{tail} {}
        List(const List&) = delete;
        List() = delete;

        static const shared_ptr<const List> insertBulk(unsigned amount) {
            struct TailGuard {
                const List* ptr;
                ~TailGuard() {
                    List::destroy(this->ptr);
                }
            } guard{};
            const List* result = insertBulk_(amount, guard.ptr);
            return amount? shared_ptr<const List>{result, List::destroy}
                         : nullptr;
        }
        static void destroy(const List* list) {
            if (!list) return;

            shared_ptr<const List> tail = list->tail;
            delete list;

            for (; tail && tail.use_count() == 1; tail = tail->tail);
        }
};

可能会切换线路。

这也可能归结为可见性问题。可能有时候其他线程无法看到效果。

检查while循环时,您不在同步部分,因此如果在其他地方调用this.isWait = isWait; *Log.d("isRun1 :" + isRun + "");* ,事情可能会同时发生变化。如上所述,线程也可能无法立即看到这些更改。

尝试将isRun和isWait声明为volatile?易失性将保证对该变量的读写不会被重新排序。这将解决问题,如果切换了我指出的上述代码部分的行,那么打印将始终在pauseNResume变量更改后发生。

但是,对于你在while循环条件检查中使用这些布尔值的方式,我建议你也使用AtomicBoolean而不是普通的布尔值。