wait()是否需要对局部变量进行同步

时间:2015-06-15 06:30:32

标签: java multithreading synchronization

我有这个代码(工作正常):

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.Utils$100000007.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在不同的线程上运行),但我被告知局部变量不应该有同步。有小费吗?谢谢!

1 个答案:

答案 0 :(得分:1)

我不知道Android开发工具,但警告听起来过于热心。编译器正试图帮助您避免在仅对单个线程可见的实例上进行同步。很聪明地知道局部变量r只能被一个线程看到,但显然知道原始线程中的rthis中的r是不够智能的。新线程都引用同一个实例。

我会尝试通过使entity MyEntity is Port( Enable : IN STD_LOGIC ; CLK : IN STD_LOGIC; SpeedOut : OUT INTEGER ); end MyEntity; Average : process type SampleArray is Array (2 downto 0) of INTEGER; variable SpeedSamples : SampleArray; begin wait until rising_edge(CLK); if ENABLE = '1' then SpeedOut <= ( SpeedSamples(0)+ SpeedSamples(1)+SpeedSamples(2) ) / 3; end if; end process Average; 成为实例变量来解决问题。