复制服务和同步
duplication service and synchronized
开始TimeThread.java里面的Service.java
重复运行 Service.java 时会出现问题。
为什么 'isWait' 值在 'Log.d("isRun1")' 中为真而在 'Log.d("isRun2")' 中为假?
我想知道 'duplicate running of service' 和 'synchronized'。
我的代码是:
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);
}
}
}
某些代码行可能会在进行优化时重新排序:
- 编译器在编译时通过重新排序来优化代码;
- JVM 可以通过重新排序来动态优化代码;
- 硬件可能会通过重新排序来优化性能。
所以代码段:
this.isWait = isWait;
*Log.d("isRun1 :" + isRun + "");*
可能换行了。
这也可能归结为可见性问题。有时效果可能对其他线程不可见。
检查您的 while 循环时,您不在同步部分,因此如果 pauseNResume
在别处调用,事情可能同时发生变化。如前所述,线程也可能不会立即看到这些更改。
尝试将 isRun 和 isWait 声明为易变的? Volatile 将保证对该变量的读写不会被重新排序。这将解决我指出的上述代码部分的行是否被切换的问题,因此打印将始终在 isWait
变量更改后发生。
但是,对于您在 while 循环条件检查中使用这些布尔值的方式,我建议您也使用 AtomicBoolean 而不是普通布尔值。
开始TimeThread.java里面的Service.java 重复运行 Service.java 时会出现问题。
为什么 'isWait' 值在 'Log.d("isRun1")' 中为真而在 'Log.d("isRun2")' 中为假?
我想知道 'duplicate running of service' 和 'synchronized'。
我的代码是:
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);
}
}
}
某些代码行可能会在进行优化时重新排序:
- 编译器在编译时通过重新排序来优化代码;
- JVM 可以通过重新排序来动态优化代码;
- 硬件可能会通过重新排序来优化性能。
所以代码段:
this.isWait = isWait;
*Log.d("isRun1 :" + isRun + "");*
可能换行了。
这也可能归结为可见性问题。有时效果可能对其他线程不可见。
检查您的 while 循环时,您不在同步部分,因此如果 pauseNResume
在别处调用,事情可能同时发生变化。如前所述,线程也可能不会立即看到这些更改。
尝试将 isRun 和 isWait 声明为易变的? Volatile 将保证对该变量的读写不会被重新排序。这将解决我指出的上述代码部分的行是否被切换的问题,因此打印将始终在 isWait
变量更改后发生。
但是,对于您在 while 循环条件检查中使用这些布尔值的方式,我建议您也使用 AtomicBoolean 而不是普通布尔值。