2012-09-17 51 views
0

我的Android應用程序中有三個服務被兩個廣播接收器觸發。前兩個寫入文件並由一個廣播接收器觸發,因此我可以確保它們一個接一個執行(通過Context.sendOrderedBroadcast())。第三個是獨立的,由一個單獨的廣播接收器觸發,但是從前一個寫入的同一個文件中讀取。併發Android服務之間的資源共享或文件鎖定

由於廣播接收器可能會在同一時間或幾乎同時被觸發,因此該文件也可能被同時訪問。我怎樣才能防止這種情況發生?我希望能夠先讀取然後寫入或寫入然後讀取。我只是不確定這個問題是否與Java併發性相似,因爲如果我沒有弄錯,android服務是完全不同的野獸。

回答

0

首先,我不應該在Service s的主UI線程中完成文件I/O。它應該在另一個線程中完成,例如AsyncTask

其次,ReentrantLock方法更容易。鎖定時,它會通知其他線程訪問相同的資源以等待,並且只有在釋放鎖定時才繼續。只需實例化一個new ReentrantLock()並在讀取或寫入文件的方法中共享該鎖。只要您需要,就可以在ReentrantLock上調用lock()unlock()

0

一個解決方案是讓您的寫作任務在訪問共享文件之前創建一個空的臨時文件(如.lock),並在完成後刪除相同的臨時文件。

您的閱讀任務可以檢查.lock文件是否存在。您也可以使用FileLock

+0

我不太確定這兩者中的哪一個都是很好的解決方案。 1)'.lock'文件的創建可能需要比服務本身已經能夠訪問文件更多的時間。 2)我只是試過了,顯然它不會工作:http://stackoverflow.com/questions/12616975/how-to-start-concurrent-threads-that-acquire-a-file-lock-and-等待彼此 –

+0

@mattquiros感謝您的反饋意見 - 如果您找到了更好的方法,請隨時添加您自己的答案(並接受它)。 – assylias

+0

不幸的是,我還沒有,雖然我被告知要看'ReentrantLock'。類似於您的建議但可與其他線程重複使用的內容。 –

0

http://developer.android.com/reference/android/app/Service.html 請注意,與其他應用程序對象一樣,服務在其宿主進程的主線程中運行。這意味着,如果你的服務要做任何CPU密集型(如MP3播放)或阻塞(如網絡)操作,它應該產生自己的線程來完成這項工作。

我建議在單獨的線程中讀取/寫入文件。您可以在同一個線程中使用Only one thread at a time!

+1

如果我在服務中產生一個單獨的線程來執行這些任務(實際上,我在考慮更多的是'AsyncTask'),那麼我是否會失去對前兩個服務的背靠背執行的控制,即使我用'sendOrderedBroadcast()'?也就是說,因爲這兩個服務在它們內部有不同的線程,所以我將無法一個接一個地執行這兩個服務。 –