簡體   English   中英

Java同步游戲:synchronized && wait && notify

[英]Java sync games: synchronized && wait && notify

我來自.NET世界,不幸的是用.NET的眼睛看Java源代碼。

以下代碼來自Android應用程序(雖然根本不是Android特定的):

    private class Worker implements Runnable {
        private final Object mLock = new Object();
        private Looper mLooper;

        Worker(String name) {
            Thread t = new Thread(null, this, name);
            t.start();
            synchronized (mLock) {
                while (mLooper == null) {
                    try {
                        mLock.wait();
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }

        public Looper getLooper() {
            return mLooper;
        }

        public void run() {
            synchronized (mLock) {
                Looper.prepare();
                mLooper = Looper.myLooper();
                mLock.notifyAll();
            }
            Looper.loop();
        }

        public void quit() {
            mLooper.quit();
        }
    }

我不清楚synchronized工作原理。 首先我認為synchronized是鎖定mLock對象,但是如果在t.start()構造函數線程首先進入同步塊之后,它將在mLock.wait()阻止它,並通過阻止它進入synchronized來隱式阻止線程“t”塊。

這顯然是錯誤的,因為我的電話按照假設:)

接下來想到同步同步“代碼塊”(在這種情況下,兩個同步塊是獨立的=>線程可以同時無限制地輸入兩個不同的同步塊),並且完全適合...

...直到我的同事告訴我mLock.wait()釋放鎖定mLock並允許其他線程同時進入mLock的關鍵部分。

我不確定我是否足夠清楚,所以很樂意回答任何進一步的問題。

查看Object.wait()上的javadoc。 這是“神奇的”,因為它會丟棄進入synchronized {}塊時獲取的監視器。 這允許另一個線程獲取監視器並調用Object.notify()

當另一個線程調用notify()從wait()調用中喚醒等待線程時,等待線程必須重新獲取監視器並將阻塞直到它可以 - 監視器僅在wait()調用期間被丟棄。 並且通知線程在新喚醒的等待線程可以繼續之前完成其同步塊。 一切都按可預測順序排列。

synchronized使用對象監視器。 在對象上調用wait()以原子方式釋放對象監視器(否則沒有其他線程可以占用監視器並向服務員發出notify )。

是。 如果您閱讀了wait()方法的描述,您將了解到它導致線程釋放鎖並阻塞,直到另一個線程在鎖上調用notifynotifyAll 當前線程等待它可以重新獲取鎖定,一旦它執行,它將繼續執行。

所示的代碼如下實踐差,但是,因為它“發布”(即,它使其他線程訪問的對象)的Worker實例被完全構造之前。 在這種方法中使用額外的障礙,結合階級的private性質,可能會使這種情況安全,但總的來說,事實並非如此。

讓我解釋:

構造函數啟動一個將執行run()方法的新線程。 這個新線程將獲得一個新的Looper對象,將其存儲在mLooper字段中,然后運行Looper消息循環。 在它之間它將通知()第一個已設置mLooper的線程。

因此,第一個線程只有在設置了mLooper之后才會從構造函數返回,這意味着第二個線程的Looper.loop()處理很快就會開始/已經開始。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM