缓存和线程问题

时间:2013-05-01 16:28:57

标签: java android multithreading queue

在我正在开发的这个应用程序中,我正在缓存来自在线的音频等内容。在应用程序的某些点,我运行批量下载内容应用程序预测用户将很快需要。所有这些都是通过我自己的缓存系统和后台线程完成的。它的基本要点是我将缓存发送给我的缓存,它将哈希值发送到文件名,然后我们搜索文件的正确位置,如果它在那里我们返回我们找到的文件的位置,如果不是我们下载该文件,然后返回该文件的位置。当我进行批处理操作时,我将它们放入队列中,这样它们就不会阻塞线程池并使其无法完成其他更高优先级的异步任务。这样,如果一个设备无法运行多个任务,那么队列在完成前一个任务时会运行一个新的异步任务,那么我现在需要完成的任务就是下一个。

这是问题所在。

如果我正在向SD卡写一个特定的音频文件,如果我在队列运行时请求它,会发生什么?两个线程可以尝试一次写入同一个文件吗?

或者它会找到该文件,并返回一个半创建和损坏的文件?

我怎么能避免这个?

我想过可能通过优先级队列运行所有内容,但是对于能够运行多个异步线程的设备,这将创建一个更加紧凑的瓶颈。

编辑:

我的应用程序涵盖了android 2.3-current

根据这个帖子 Running multiple AsyncTasks at the same time -- not possible?

似乎取决于操作系统/设备版本,任务可以并行运行(一次全部到极限)或一次一个地运行。

xD这就是我试图自己管理它们的原因。

2 个答案:

答案 0 :(得分:1)

根据您的操作系统,您可能能够同时写入同一文件,例如,Windows不会让2个进程锁定同一个文件。但是同时写作并不能保证你所写的内容会有用,你几乎肯定会破坏文件。

可能最好的办法就是像你提到的那样为设备设置一个中央编写器,或者你可以有一个锁定方案,让多个编写者很好地等待另一个完成。

答案 1 :(得分: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保护,这将阻止多个线程写入相同的文件名。