2013-05-01 89 views
0

在這個應用程序我正在努力,我緩存內容,如音頻來自在線。在應用程序的某些時候,我會在應用程序預測用戶需要的內容上運行批量下載。所有這些都是通過我自己的緩存系統和後臺線程完成的。它的基本要點是,我發送緩存的網址,它的哈希到一個文件名,然後我們搜索文件的正確位置,如果它在那裏,我們返回我們找到的文件的位置,如果不是我們下載該文件,然後返回該文件的位置。當我執行批處理操作時,我將它們放入隊列中,以便它們不會堵塞線程池,並且無法完成其他更高優先級的異步任務。這種方式是因爲如果設備無法運行多個任務,則隊列在完成前一個任務時運行一個新的異步任務,那麼現在我需要完成的任務將排在後面。高速緩存和線程問題

這裏是問題。

如果我目前正在寫一個特定的音頻文件到SD卡上,如果我要求它作爲隊列運行它,會發生什麼?兩個線程可以一次寫入同一個文件嗎?

還是會找到該文件,並返回一個半創建和損壞的文件?

我該如何避免這種情況?

我已經想到了可能通過優先級隊列運行的一切,但與能夠運行多個異步線程這將創建一個更緊密的瓶頸設備。

編輯:

我的應用程序適用於Android 2.3電流

根據這個線索 Running multiple AsyncTasks at the same time -- not possible?

似乎

,取決於該任務可以並行運行的OS /設備版本(全一次達到極限)或一次一個。

的xD這就是爲什麼我嘗試來管理他們自己。

回答

1

可以使用ConcurrentHashMap避免多線程寫入同一文件的問題。

ConcurrentHashMap<String, Boolean> map = new ConcurrentHashMap<>(); 

public void writeToFile(String fileName, byte[] data) { 
    // putIfAbsent returns the value previously associated with fileName, or null 
    if(map.putIfAbsent(fileName, Boolean.TRUE) == null) { 
     try(FileOutputStream stream = new FileOutputStream(fileName)){ 
      stream.write(data); 
     } finally { 
      map.remove(filename); 
     } 
    } 
} 

只要所有線程使用putIfAbsent後衛,這將防止多個線程寫入相同的文件名。

1

根據您的操作系統,您可能可以同時寫入同一文件,例如Windows不會讓兩個進程鎖定同一文件。但是,同時書寫並不能保證你所寫的內容是有用的順序,你幾乎肯定會損壞文件。

可能是做的最好的事情是對設備的中央作家像你提到的,或者你可以有一個鎖定方案,其中多個作家很好地等待對方完成。