2011-07-27 23 views
5

我有一個線程鎖定了在我的Android應用程序仍有一些未知的原因,每當我試圖殺死從線程A線程B的一個問題(通常,有時它的工作)。我猜想這是因爲我的一些方法在線程間進行調用而未被同步。我製作了取消方法和許多基本上是事件處理程序同步的方法,並使幾個共享變量變得不穩定並且一切正常。在Java中同步聲明方法進行權衡?

我不知道是哪20個奇揮發性/同步聲明我實際上增加解決了這個問題,這讓我開始思考「我應該在乎嗎?它的工作原理不惹它!」中

所以,我的問題是:是否與聲明同步的方法或原揮發掉相關的任何交易?如果不需要這些聲明,是否有任何理由避免這些聲明?

編輯
的問題線程(S)是接收/發送數據流,這樣的AsyncTask和其他輔助線程型的解決方案並不能很好地工作藍牙連接。它們設計用於執行有限的任務,並在完成時終止。一些像ASyncTask一樣,也增加了很多簡單的殺死應用程序的開銷。對於像這樣持續運行的線程,使用線程仍然是最好的方法。

我使用的是Android Service生成和管理線程,所以我下面在這方面Android的設計範例。

+0

有一個(小?)固有的性能損失。很難說出「鎖定線程的問題」是什麼(輪詢非易失性成員字段?),但是自由添加「synchronized」聽起來像是一個解決死鎖的好方法,並且您怎麼知道您的應用程序是沒有比賽條件?最大的問題是你在線程之間有很多共享狀態 - 你需要決定什麼需要共享,確保共享狀態是線程安全的(儘可能地提供不可變的幫助),並決定線程如何通信(Handler/ConcurrentLinkedQueue/LinkedBlockingQueue?)。 –

回答

-1

如果它的工作現在不解決它的:),而是爲下一個項目,你應該考慮使用AsyncTaskDev Guide。我認爲性能影響在Android環境中並不是真正的問題,但複雜性,可讀性和未來的可維護性會成爲一個問題(取消/終止線程,許多共享變量)。

+0

我瞭解ASyncTask,但這是一個需要不斷運行的線程的藍牙通信應用程序。 ASyncTask適用於將來在有限時間結束的單一任務,而不是穩定的連接。 ASyncTask很棒,但它不是一個神奇的子彈。 – CodeFusionMobile

+0

對不起,我不知道你在哪裏使用它,但基於'20奇怪volatile/synchronized'對於Java程序來說仍然非常複雜。 – user802421

+2

對於背景藍牙通信,您不應該將其作爲正在進行的服務嗎?讓Android系統管理您的服務線程,並讓您的應用程序與服務對話。 – fluffy

4

根據我的經驗,通過使用同步(對象){...}訪問特定對象,儘可能在更細粒度的級別上執行鎖定通常更簡單,而且通常更具性能。另外,如果您必須同時獲得多個鎖,請始終確保您始終以相同的順序獲取它們。

靜態方法都有自己的古怪擔心的塊;一個同步實例方法將只與該實例同步,而不是作爲整體的類同步,因此如果需要在實例方法中同步兩者,則需要執行類似synchronized(this.class)的操作。 。}同樣,儘管如果你正在應用上面的內容,那麼你真的只是在你用特定方法訪問的靜態字段上進行synchronized()。

另外需要說明的是,一般情況下,您不希望產生自己的線程,而應該使用系統預先存在的線程管理機制(例如ThreadPoolExecutor用於正在進行的工作隊列或AsyncTask用於異步UI更新) 。 ThreadPoolExecutor往往更具性能(並且可以更好地利用多核設備),但是如果要向UI執行操作,則必須做一些額外的工作;另一方面,AsyncTask往往會慢一點,也更重一些,但它也會在UI線程中運行onPostExecute回調。

+0

所有這些方法(ThreadPool,ASyncTask等)都設計用於運行任務或某種形式的重處理,這些處理將在作業完成時終止。我正在管理一個活動的藍牙連接併發送數十個不同的數據包,並監視大量的連接狀態和變量。對於像這樣的非終止進程,ASyncTask和工作線程不是正確的選擇。 – CodeFusionMobile

+0

好的。我的第三段更多的是作爲一般的經驗法則,而不是特定於編輯過的您的問題,但它仍然是一般要記住的事情。 – fluffy