2013-05-01 73 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不会让两个进程锁定同一文件。但是,同时书写并不能保证你所写的内容是有用的顺序,你几乎肯定会损坏文件。

可能是做的最好的事情是对设备的中央作家像你提到的,或者你可以有一个锁定方案,其中多个作家很好地等待对方完成。