0

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

这是问题所在。

如果我当前正在将某个音频文件写入 sd 卡,如果我在队列运行时请求它,会发生什么?两个线程可以尝试一次写入同一个文件吗?

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

我该如何避免这种情况?

我曾想过可能通过优先级队列运行所有内容,但是对于能够运行多个异步线程的设备,这将产生更严格的瓶颈。

编辑:

我的应用涵盖 android 2.3-current

根据这个线程 同时运行多个 AsyncTasks -- 不可能吗?

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

xD 这就是为什么我要自己管理它们。

4

2 回答 2

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保护,这将防止多个线程写入相同的文件名。

于 2013-05-01T16:41:57.367 回答
1

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

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

于 2013-05-01T16:35:42.187 回答