在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);
}
}
}
答案 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而不是普通的布尔值。