wait() 是否需要同步局部变量
Does wait() need synchronization on local variable
我有这段代码(运行良好):
public static void runOnUiThread(Activity c, final Runnable action) {
// Check if we are on the UI Thread
if (Looper.getMainLooper() == Looper.myLooper()) {
// If we are, execute immediately
action.run();
return;
} // Else run the runnable on the UI Thread and wait
Runnable r = new Runnable() {
@Override
public void run() {
action.run();
synchronized (this) {
this.notify();
}
}
};
synchronized (r) {
try {
c.runOnUiThread(r);
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
我收到了 Synchronization on local variable
警告。按照建议,我删除了局部变量的同步,以修复警告:
public static void runOnUiThread(Activity c, final Runnable action) {
// Check if we are on the UI Thread
if (Looper.getMainLooper() == Looper.myLooper()) {
// If we are, execute immediately
action.run();
return;
} // Else run the runnable on the UI Thread and wait
Runnable r = new Runnable() {
@Override
public void run() {
action.run();
this.notify();
}
}
try {
c.runOnUiThread(r);
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
现在调用此方法时出现异常:
06-15 09:18:13.252 27282 27282 E AndroidRuntime FATAL EXCEPTION: main
06-15 09:18:13.252 27282 27282 E AndroidRuntime java.lang.IllegalMonitorStateException: object not locked by thread before notify()
06-15 09:18:13.252 27282 27282 E AndroidRuntime at java.lang.Object.notify(Native Method)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at org.matapps.android.simpleappcreator.Utils0000007.run(Utils.java:673)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at android.os.Handler.handleCallback(Handler.java:615)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at android.os.Handler.dispatchMessage(Handler.java:92)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at android.os.Looper.loop(Looper.java:137)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at android.app.ActivityThread.main(ActivityThread.java:4867)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at java.lang.reflect.Method.invokeNative(Native Method)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at java.lang.reflect.Method.invoke(Method.java:511)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
我很确定我需要同步(因为 runnable 在不同的线程上运行),但我被告知局部变量不应该有同步。有小费吗?谢谢!
我不知道 Android 开发工具,但警告听起来过于热心。编译器试图帮助您避免在仅对单个线程可见的实例上进行同步。知道局部变量r
只能被一个线程看到就够聪明了,但是知道原线程中的r
和新线程中的this
显然不够聪明新线程都引用同一个实例。
我会尝试通过使 r
成为一个实例变量来解决这个问题。
我有这段代码(运行良好):
public static void runOnUiThread(Activity c, final Runnable action) {
// Check if we are on the UI Thread
if (Looper.getMainLooper() == Looper.myLooper()) {
// If we are, execute immediately
action.run();
return;
} // Else run the runnable on the UI Thread and wait
Runnable r = new Runnable() {
@Override
public void run() {
action.run();
synchronized (this) {
this.notify();
}
}
};
synchronized (r) {
try {
c.runOnUiThread(r);
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
我收到了 Synchronization on local variable
警告。按照建议,我删除了局部变量的同步,以修复警告:
public static void runOnUiThread(Activity c, final Runnable action) {
// Check if we are on the UI Thread
if (Looper.getMainLooper() == Looper.myLooper()) {
// If we are, execute immediately
action.run();
return;
} // Else run the runnable on the UI Thread and wait
Runnable r = new Runnable() {
@Override
public void run() {
action.run();
this.notify();
}
}
try {
c.runOnUiThread(r);
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
现在调用此方法时出现异常:
06-15 09:18:13.252 27282 27282 E AndroidRuntime FATAL EXCEPTION: main
06-15 09:18:13.252 27282 27282 E AndroidRuntime java.lang.IllegalMonitorStateException: object not locked by thread before notify()
06-15 09:18:13.252 27282 27282 E AndroidRuntime at java.lang.Object.notify(Native Method)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at org.matapps.android.simpleappcreator.Utils0000007.run(Utils.java:673)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at android.os.Handler.handleCallback(Handler.java:615)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at android.os.Handler.dispatchMessage(Handler.java:92)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at android.os.Looper.loop(Looper.java:137)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at android.app.ActivityThread.main(ActivityThread.java:4867)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at java.lang.reflect.Method.invokeNative(Native Method)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at java.lang.reflect.Method.invoke(Method.java:511)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
06-15 09:18:13.252 27282 27282 E AndroidRuntime at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
我很确定我需要同步(因为 runnable 在不同的线程上运行),但我被告知局部变量不应该有同步。有小费吗?谢谢!
我不知道 Android 开发工具,但警告听起来过于热心。编译器试图帮助您避免在仅对单个线程可见的实例上进行同步。知道局部变量r
只能被一个线程看到就够聪明了,但是知道原线程中的r
和新线程中的this
显然不够聪明新线程都引用同一个实例。
我会尝试通过使 r
成为一个实例变量来解决这个问题。